次の点を考慮してください。
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
OK、誇張しました: 実際、これをテストしたすべての Internet Explorer (IE8-11、さらには MS Edge!) は同じように動作します。それでも、何?
更新:それは奇妙になります:
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 では明らかにいくつかのコーナーをカットしようとします。
免責事項:浮動小数点演算には多少の欠陥があることは知っています。私が理解していないのは、IE と他のブラウザーの世界との違いは何かということです。