javascript - Number.prototype.toFixed : amazingly correct in Internet Explorer

标签 javascript internet-explorer floating-point

考虑以下因素:

var x = 2.175;
console.log(x.toFixed(2));  // 2.17

什么?不,这并不奇怪。这是相当明显的,请参阅:数字文字 2.175实际上(根据 IEEE-754 规则)作为一个比 2.175 小一点点的值存储在内存中。这很容易证明:

console.log(x.toFixed(20)); // 2.17499999999999982236

这就是它在 32 位 Windows 设置上的最新版本 Firefox、Chrome 和 Opera 中的工作原理。但这不是问题。

真正的问题是 Internet Explorer 6 (!) 如何像人类一样正确做到这一点:

var x = 2.175;
console.log(x.toFixed(2));  // 2.18
console.log(x.toFixed(20)); // 2.17500000000000000000

好吧,我夸大了:实际上我测试过的所有 Internet Explorer(IE8-11,甚至 MS Edge!)的行为方式都相同。仍然,WAT?

更新:变得更奇怪:

x=1.0;while((x-=0.1) > 0) console.log(x.toFixed(20));

IE                        Chrome
0.90000000000000000000    0.90000000000000002220
0.80000000000000000000    0.80000000000000004441
0.70000000000000010000    0.70000000000000006661
0.60000000000000010000    0.60000000000000008882
0.50000000000000010000    0.50000000000000011102
0.40000000000000013000    0.40000000000000013323
0.30000000000000015000    0.30000000000000015543
0.20000000000000015000    0.20000000000000014988
0.10000000000000014000    0.10000000000000014433
0.00000000000000013878    0.00000000000000013878

除了最后一个之外,为什么会有差异?为什么最后一个没有区别? x=0.1; while(x-=0.01)... 非常相似顺便说一句:直到我们非常接近零,toFixed IE 显然试图走捷径。

免责声明:I do知道 float 学有点缺陷。我不明白的是 IE 和其他浏览器世界有什么区别。

最佳答案

所报告的行为偏离 ECMA specification 的要求.

根据第 8.5 条,Number 类型具有 IEEE-754 64 位二进制值,但只有一个 NaN。所以2.175无法准确表示;您可以获得的最接近的是 2.17499999999999982236431605997495353221893310546875。

根据 15.7.4.5,toFixed(20) 使用的算法可归结为:

  • “设 n 为一个整数,其精确数学值为 n ÷ 10f – < em>x 尽可能接近于零。如果有两个这样的n,则选择较大的n。”
  • 上面的f是20(请求的位数),x是操作数,应该是2.17499999999999982236431605997495353221893310546875。
  • 这会导致为 n 选择 217499999999999982236。
  • 然后对 n 进行格式化,生成“2.174999999999999982236”。

关于javascript - Number.prototype.toFixed : amazingly correct in Internet Explorer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19166098/

相关文章:

javascript - 有没有办法将对象传递给 casper.js 的 evaluate()?

javascript - Flash 阻塞 javascript 事件

Java:如何使用正则表达式将字符串分成几部分?

binary - 我的 IEEE 754 浮点表示有什么问题?

javascript - IE 低于 11,jquery Easydropdown 不选择下拉列表中的最后一项

python - 在python中删除指数格式的前导0

javascript - 在 JavaScript 中缓存 onclick 对象

javascript - 在 onMouseOut 上调用 javascript 函数

javascript - 无法从数据集制作饼图

html - Internet Explorer 7 菜单换行