Number.prototype.toFixed:在Internet Explorer中非常正确 [英] Number.prototype.toFixed: amazingly correct in Internet Explorer

查看:267
本文介绍了Number.prototype.toFixed:在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

  • 是20(请求的数字位数),而 x 是操作数,它应该是2.17499999999999982236431605997495353221893310546875。

  • 这导致选择217499999999999982236 n
  • 然后 n 被格式化,产生2.17499999999999982236。

  • 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 ÷ 10fx 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆