JavaScript或IEEE-754中的舍入怪癖?

JavaScript或IEEE-754中的舍入怪癖?,javascript,math,ieee-754,Javascript,Math,Ieee 754,在我的一个单元测试中,我遇到了一个奇怪的问题,在JavaScript中得到了意想不到的舍入结果: (2.005).toFixed(2) // produces "2.00" (2.00501).toFixed(2) // produces "2.01" 起初我怀疑这只是Webkit的问题,但它在Gecko中重新出现,这对我来说意味着这是ECMA-262或IEEE-754的预期副作用。我假设2.005的二进制表示法稍微少一点?或者ECMA-262是否为toFixed指定了一种从圆到偶的方法 有

在我的一个单元测试中,我遇到了一个奇怪的问题,在JavaScript中得到了意想不到的舍入结果:

(2.005).toFixed(2)
// produces "2.00"

(2.00501).toFixed(2)
// produces "2.01"
起初我怀疑这只是Webkit的问题,但它在Gecko中重新出现,这对我来说意味着这是ECMA-262或IEEE-754的预期副作用。我假设2.005的二进制表示法稍微少一点?或者ECMA-262是否为
toFixed
指定了一种从圆到偶的方法

有人愿意透露一些关于引擎盖下发生的事情的见解,让我安心吗

更新:感谢您的评论

我要补充的是,让我有点紧张的一件事是在Webkit
dtoa.cpp
中的快速搜索中发现的评论,这似乎意味着有多条取整路径,开发人员不确定它是如何工作的,包括相关的
修复程序


另外,这并不意味着什么,但IE9按照我的预期对其进行了循环,这意味着它不是ECMA-262的一部分,或者它们有一个bug。

如果规范自ECMA 262草案(2011年3月5.1版)以来没有更改,
(2.005)。toFixed(2)
必须返回字符串
“2.00”
,因为“数值”是

与双精度64位二进制格式IEEE 754值相对应的原语值

7.8.3和8.5中规定了数字文字的解释,以符合IEEE 754“四舍五入到最近”模式(将关系四舍五入到偶数有效位),对于
2.005
,该模式产生的值为

x = 4514858626438922 * 2^(-51) = 2.00499999999999989341858963598497211933135986328125
在第15.7.4.5节中,涉及固定的相关步骤8。A.是:

n
为整数,其
n
÷10f–
x
的精确数学值尽可能接近零。如果有两个这样的
n
,选择较大的
n

而且
2.00-x
2.01-x
更接近于零,因此
n
在这里必须是200。然后以自然的方式转换为字符串

此外,这并不意味着什么,但IE9像我预期的那样对其进行了处理,这意味着它不是ECMA-262的一部分,或者它们有一个bug


虫子。也许他们试着用简单的方法,用
10^digits
和四舍五入进行乘法
x*100
正好是
200.5
,因此会产生一个字符串
“2.01”
2.005
很可能实际上是二进制浮点的
2.004999999999999934185893598497211933135986328125可能有很多相关文章的链接,最重要的链接是@EliasVanOotegem具有讽刺意味的是,当我发现这一点时,我正在使用
toFixed
来绕过其中一种怪癖!为此,我在Haskell库中定义了。如果您要求足够高的精度(
%.52f
对于值
=1
),您也可以从gcc获得完整的表示,但由于我总是运行ghci,因此要求的速度更快。完美。这正是我想要的。谢谢