这个JavaScript演示了IE中的一个错误,它现在让我感到疯狂:
var y = 6044629098073143; // this exact integer easily fits into an IEEE double
document.write(y + " " + Math.round(y)+"<br><br>");
IE 8(和Opera 12.02)中的输出显示Math.round
关闭1:
6044629098073143 6044629098073144
Firefox,Chrome和Safari中的输出是正确的。
IE和Opera在这方面究竟发生了什么?
答案 0 :(得分:3)
我已经确认了RobG的评论:所有浏览器中的所有整数都低于2 ^ 52(4503599627370496)。高于此舍入的整数UP到IE / Opera中使用Math.round的EVEN编号(而其他浏览器正确舍入)。
正如RobG所提到的,IE和Opera很可能将Math.round(x)实现为Math.floor(x + 0.5),这导致了这些结果,因为将值0.5添加到&gt; 2 ^ 52产生不精确的结果。更聪明的round()实现将使用FPU的原生舍入支持(IE和Opera开发人员,请注意并修复!)
与此同时,此解决方法应该有效:
// workaround for IE and Opera's brain-dead Math.round() implementation
if (y < 4503599627370496) // 2^52
{
y = Math.round(y);
}
// else 'y' is already an integer
答案 1 :(得分:1)
在Opera IE浏览器中,RobG在上述评论中指出,保证最大的Integer值为4503599627370496(2 ^ 52)。
有趣的是,这也适用于某些部分的浮点值。 对于大于此数字的数字,浮点数也会失去准确性 如您所见here,双精度数的尾数精度为52位。这意味着,对于大于4503599627370496的所有数字,将修剪最后一个数字,因为尾数始终与所表示数字的最高有效位(MSB)对齐。
键入Opera的控制台:
//This works
>>> 4503599627370494.5 //Consumes 53 bits
4503599627370494.5
>>> 4503599627370495.5 //Consumes 53 bits
4503599627370495.5
//This works no more, the last bit is now needed
>>> 4503599627370496.5 //Consumes 54 bits
4503599627370496
这种精确度的损失解释了为什么这些浏览器没有准确的数字表示,最后一点简单地消失了。另见Machine_epsilon.
但是,你可以从这个观察中得出的结论是,问题中显示的整数肯定会转换为双数。