考虑以下因素:
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/