JavaScriptのtoFixedの結果は四捨五入というわけではないよう

JavaScriptの数値型にはtoFixedというメソッドが割り当てられており、これを使う事で指定の小数点以下の表記で整形することができます。
Number.prototype.toFixed() – JavaScript | MDN

例えば、「(1).toFixed(2)」とすると結果は「1.00」となり、「(1.234).toFixed(2)」とすると結果は「1.23」となります。

このtoFixedですが、調べてみると切り捨てられた箇所は四捨五入になるという書かれたサイトをよく見かけるのですが、試してみると四捨五入にならない場合もあるようです。

例えば、Chrome(v108.0.5359.125)やFireFox(v108.0.1)では下記のようになりました。

1.15を小数点第二位で四捨五入したら1.2になりそうですが、実際には1.1となっています。小数点第一位が偶数か奇数かというのも関係なさそうです(たまに、偶数か奇数かで判断して切り捨てるか切り上げるかを判断する方法もあるようです)。
なぜこうなるのかは調べてもよく分かりませんでした。最後が5で終わる小数は2進数で表しても循環小数にならないですし…。
とにかく、toFixedは近似値で丸め込まれるとのことで、四捨五入になるとは保証されてないようなので、気を付けてつかったほうがよさそうです。

動作サンプル:

See the Pen
toFixed(1)の四捨五入テスト
by amano225 (@amano225)
on CodePen.

なお、試しにIE11でどうなるか試してみると、こちらは正しく、四捨五入されました。

久々にIE11でJavaScript動かそうとしたら、アロー関数だったり、NodeListでforEachを使っているところでエラーとなって書き換える必要がありました。本当、業務ではIE11対応から解放されてよかったと思います。
ついでに、IE11で動かしたコードも載せておきます。

<ul>
  <li>(1.05).toFixed(1)=<span data-num="1.05"></span></li>
  <li>(1.15).toFixed(1)=<span data-num="1.15"></span></li>
  <li>(1.25).toFixed(1)=<span data-num="1.25"></span></li>
  <li>(1.35).toFixed(1)=<span data-num="1.35"></span></li>
  <li>(1.45).toFixed(1)=<span data-num="1.45"></span></li>
  <li>(1.55).toFixed(1)=<span data-num="1.55"></span></li>
  <li>(1.65).toFixed(1)=<span data-num="1.65"></span></li>
  <li>(1.75).toFixed(1)=<span data-num="1.75"></span></li>
  <li>(1.85).toFixed(1)=<span data-num="1.85"></span></li>
  <li>(1.95).toFixed(1)=<span data-num="1.95"></span></li>
</ul>
<script>
window.addEventListener('DOMContentLoaded', function(event){
    const resultSpans = document.querySelectorAll('[data-num]');
    for(var i = 0; i < resultSpans.length; i++){
    	const span = resultSpans[i];
	    const num = Number(span.dataset.num);
	    
	    span.innerHTML = num.toFixed(1);
    }
});
</script>

コメント

タイトルとURLをコピーしました