Number.prototype.toFixed:在Internet Explorer中非常正确 [英] Number.prototype.toFixed: amazingly correct in Internet Explorer
问题描述
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位版本的Firefox,Chrome和Opera上,位Windows安装程序。但是这不是问题。真正的问题是Internet Explorer 6 (!)实际上是如何设置的 right del>与人类一样:
var x = 2.175;
console.log(x.toFixed(2)); // 2.18
console.log(x.toFixed(20));好吧,我超量程化了:实际上我测试过的所有Internet Explorer(IE8-11,IE8-11,甚至MS Edge!)的行为也是一样的。还有,WAT?
更新:变得更加陌生:
((x- = 0.1)> 0)console.log(x.toFixed(20));
IE浏览器
0.90000000000000000000 0.90000000000000002220
0.80000000000000000000 0.80000000000004441
0.700000000000010000 0.70000000000000006661
0.6000000000000100100 0.6000000000000888
0.5000000000000100100 0.500000000000011102
0.40000000000000013000 0.400000000000013133
0.30000000000000015000 0.3000000000000151543
0.20000000000000015000 0.20000000000000014988
0.10000000000000014000 0.1000000000000141433
0.00000000000000013878 0.00000000000000013878
差别 - 除了最后一个之外呢?为什么在最后一个没有区别?这是非常相似的 x = 0.1; while(x- = 0.01)...
,顺便说一句:直到我们非常接近零,IE中的 toFixed
显然试图切一些角落。
免责声明:我做知那浮点数学有点不对劲。我不明白的是IE和浏览器世界的其他部分有什么不同。
报告的行为偏离了 ECMA规范的要求。
根据第8.5节, Number
类型具有IEEE-754 64位二进制值,但只有一个NaN。所以2.175不能完全表示;你可以得到最接近的是2.17499999999999982236431605997495353221893310546875。
每15.7.4.5, toFixed(20)
使用一个沸腾的算法 / em>÷10 f - x 尽可能接近零。如果有两个这样的 n ,请选择较大的 n 。
Consider the following:
var x = 2.175;
console.log(x.toFixed(2)); // 2.17
What? No, no surprise here. That's rather obvious, see: Number literal 2.175
is actually stored in memory (by IEEE-754 rules) as a value that's just a tiny little bit smaller than 2.175. And that's easy to prove:
console.log(x.toFixed(20)); // 2.17499999999999982236
That's how it works in the latest versions of Firefox, Chrome, and Opera on 32-bit Windows setup. But that's not the question.
The real question is how Internet Explorer 6 (!) actually manages to do it right as humans do:
var x = 2.175;
console.log(x.toFixed(2)); // 2.18
console.log(x.toFixed(20)); // 2.17500000000000000000
OK, I overdramatized: actually all Internet Explorers I tested this on (IE8-11, and even MS Edge!) behave the same way. Still, WAT?
UPDATE: It gets stranger:
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
Why the difference - in all but the last one? And why no difference in the last one? It's very similar for x=0.1; while(x-=0.01)...
, by the way: until we get very close to zero, toFixed
in IE apparently attempts to cut some corners.
Disclaimer: I do know that floating-point math is kinda flawed. What I don't understand is what's the difference between IE and the rest of the browser's world.
The reported behavior deviates from the requirements of the ECMA specification.
Per clause 8.5, the Number
type has the IEEE-754 64-bit binary values, except there is only one NaN. So 2.175 cannot be represented exactly; the closest you can get is 2.17499999999999982236431605997495353221893310546875.
Per 15.7.4.5, toFixed(20)
uses an algorithm that boils down to:
- "Let n be an integer for which the exact mathematical value of n ÷ 10f – x is as close to zero as possible. If there are two such n, pick the larger n."
- In the above, f is 20 (the number of digits requested), and x is the operand, which should be 2.17499999999999982236431605997495353221893310546875.
- This results in selecting 217499999999999982236 for n.
- Then n is formatted, producing "2.17499999999999982236".
这篇关于Number.prototype.toFixed:在Internet Explorer中非常正确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!