IEのNumber.toFixed()の挙動が四捨五入としては微妙な件
JavaScriptで四捨五入する方法をググるとNumber.toFixed()で出来るよ、Math.round()よりこっちの方が桁数指定できて嬉しいよ、みたいな情報にたどり着いたり着かなかったりするわけですが、IEでだいたい0.5<=n<1のときに桁数0を指定すると結果が期待に沿わないっぽいです。
- n=0.55
Math.round(n) | n.toFixed(0) | n.toFixed(1) | |
---|---|---|---|
IE7 on WindowsXP SP2 | 1 | 0 | 0.6 |
Firefox 2.0.0.11 on WindowsXP SP2 | 1 | 1 | 0.6 |
Safari 3.0.4 on Mac OS X 10.5.1 | 1 | 1 | 0.6 |
- n=0.85
Math.round(n) | n.toFixed(0) | n.toFixed(1) | |
---|---|---|---|
IE7 on WindowsXP SP2 | 1 | 0 | 0.9 |
Firefox 2.0.0.11 on WindowsXP SP2 | 1 | 1 | 0.8 |
Safari 3.0.4 on Mac OS X 10.5.1 | 1 | 1 | 0.8 |
- n=1.55
Math.round(n) | n.toFixed(0) | n.toFixed(1) | |
---|---|---|---|
IE7 on WindowsXP SP2 | 2 | 2 | 1.6 |
Firefox 2.0.0.11 on WindowsXP SP2 | 2 | 2 | 1.6 |
Safari 3.0.4 on Mac OS X 10.5.1 | 2 | 2 | 1.6 |
その他にも浮動小数点の誤差なんかも関係してくるとは思いますが、豪快に違う例を挙げました。ちゃんと見てませんがIE6でも同様の結果だったはず。
結論としては、IEのNumber.toFixed()は四捨五入としてちょっとおかしいので、面倒でもMath.round()を使った方がよいでしょう。そもそもECMAScriptの仕様書(http://www.ecma-international.org/publications/standards/Ecma-262.htm)には何て書いてるのか、という話もありますが、ざっくり見た限りだとIEの挙動が間違ってるような気がするのですが、どうもよくわからない。
一応検証したコードを。
var srcs = [0.55,0.85,1.55]; for (var i=0; i<srcs.length; i++) { alert(Math.round(srcs[i])); alert(srcs[i].toFixed(0)); alert(srcs[i].toFixed(1)); }
追記:少し似たようなことを書いている人を発見(http://d.hatena.ne.jp/onozaty/20070512/p1)。