【JS】JavaScriptにおける数値の誤差

誤差パターン1:64ビット倍精度の数字範囲を超える場合

 * JavaScriptの数値は「IEEE754」という規格に従って「64ビット倍精度」で行っている
  => 「64ビット倍精度」の数値範囲は、「-1.79769×10の308乗~1.79769×10の308乗」

var result1 = Math.pow(2, 55);

誤差パターン2:小数点を含む計算を行う場合

 * 浮動小数点での計算誤差

var result1 = 4.321 * 100;
var result2 = 67 - 66.9;

サンプル

<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<form>
<div id="result1_1">result1_1</div>
<div id="result1_2">result1_2</div>
<div id="result2_1">result2_1</div>
<div id="result2_2">result2_2</div>
<input id="fire" type="button" value="click me!" onClick="sample()">
</form>
<script>
function sample() {
   var result1_1 = Math.pow(2, 55);
   var result1_2 = 76287755398823936;
   var result2_1 = 4.321 * 100;
   var result2_2 = 67 - 66.9;
   
   document.getElementById("result1_1").innerHTML = result1_1;
   document.getElementById("result1_2").innerHTML = result1_2;
   document.getElementById("result2_1").innerHTML = result2_1;
   document.getElementById("result2_2").innerHTML = result2_2;
}
</script>
</body>
</html>

出力結果

Firefox / Chrome
36028797018963970
76287755398823940
432.09999999999997
0.09999999999999432
IE11
36028797018963970
76287755398823930
432.09999999999996
0.09999999999999431

対策

端数処理を行う

 * 端数処理(四捨五入、切り上げ、切り下げ)を行う

ツールを使用する

 * 以下のサイトを参照のこと。
http://laxmi759.blog.fc2.com/blog-entry-92.html
http://qiita.com/coa00@github/items/0226a6b2e1188729521b


関連記事

浮動小数点と誤差

http://blogs.yahoo.co.jp/dk521123/35833686.html

Y軸のラベルが浮動小数点の誤差で表示がおかしくなる

http://blogs.yahoo.co.jp/dk521123/35833804.html