提问人:runtimeerror 提问时间:2/14/2022 最后编辑:runtimeerror 更新时间:2/14/2022 访问量:778
为什么 JavaScript 中的 0.3 + 0 == 0.3 和 0.1 + 0 == 0.1 不能完全用二进制表示
why 0.3 + 0 == 0.3 and 0.1 + 0 == 0.1 in javascript when 0.3 and 0.1 cannot be represented exactly in binary
问:
第一个问题: 如果我们这样做,在 java 脚本中。
0.2 + 0.1
=>0.30000000000000004
因为 0.2,0.1 四舍五入为不同的数字,总和也四舍五入为不同的数字 本文解释了幕后花絮。我明白这一点,但是 当我这样做时。
0.3 + 0
=>0.3
它显示 0.3 为什么?0.3 不能完全用二进制表示,应该四舍五入到不同的数字,对吧?。
因此,0.3 + 0 的值应该是 0.3 的四舍五入数和总和(如果需要的话)。
第二个问题:
我们什么时候这样做。
let x = 0.3
由于 0.3 不能用二进制精确表示,它被四舍五入到另一个数字,但是当您访问变量 x 时,为什么它显示 0.3 而不是实际四舍五入的数字。
x
=>0.3
但是当你这样做时。
0.2 + 0.1
=>0.30000000000000004
它显示数字的实际舍入,但不是 0.3。 请解释。
答:
5赞
T.J. Crowder
2/14/2022
#1
加法时得到的值和从文字中得到的值是不同的值(两者都不是正好 3/10,两者都非常接近)。(添加无关紧要,它不会更改要添加到的数字的值。你得到的那个刚刚超过3/10;你得到的那个(如果我没记错的话)不到 3/10。0.1
0.2
0.3
0
0.1 + 0.2
0.3
在将浮点数转换为文本时,JavaScript 遵循通常的做法,即仅包含所需的数字数,以将其与格式可以表示的下一个最接近的值区分开来(规范和规范引用的学术论文中的详细信息)。 不需要任何额外的数字来区分,但确实如此(我猜要将其与 区分开来,但我实际上并不知道)。0.3
0.30000000000000004
0.3
评论
0赞
runtimeerror
2/14/2022
从这些文章中很难理解。目前,这些文章中有很多东西超出了我的知识范围。但如果有人能用简单的方式解释它,举个例子,一步一步地解释,我会很高兴。
0赞
T.J. Crowder
2/14/2022
@runtimeerror - 从字面上看,最基本的是,当你得到数字的字符串时,它并不完全是数字是什么。只需确保将字符串转换回数字即可获得相同的数字。 IIRC 是(或类似的东西),但由于这是您转换回数字时得到的,因此这是用于与人类交互的字符串。 之所以显示为 ,是因为它需要与 区分开来。"0.3"
0.3
0.3
0.299999999999998
"0.3"
0.1 + 0.2
"0.30000000000000004"
"0.3"
0赞
runtimeerror
2/14/2022
这样展示是不是错了。因为当您将 0.3 指定为文字但在引擎盖下时,它被存储为不同的数字。检索时,它不会显示实际存储的值。这让人们认为他们实际上存储了 0.3,但事实并非如此。这不会导致不必要的错误和混乱吗?
1赞
T.J. Crowder
2/14/2022
@runtimeerror - 高效的浮点数是精度、大小和运行时成本之间的折衷方案;更多内容请点击此处。是的,人们经常遇到麻烦,因为他们没有意识到他们使用的浮点数的局限性。值得庆幸的是,在当今世界,与定义 IEEE-754 binary64 格式时相比,内存和处理器速度要快得多,我们越来越多地获得其他选择(包括相对较新的 IEEE-754 decimal128)。JavaScript的...
1赞
T.J. Crowder
2/14/2022
...将很快获得某种十进制类型(C# 已经有一个)。同时,当 IEEE-754 binary64 没有您需要的精度(例如财务计算)时,您可以使用一些库。至于它是否具有误导性,这是一个价值判断,我不打算评论,只是说很多东西的设计和思考已经投入到这些东西的设计中——比如我上面引用的那篇论文。:-)
评论
0.3
0.3
0.3