小数を四則演算すると微妙な誤差が生じます。
消費税の計算などきっちりした値がほしいときには困ります。
10進数で計算すると誤差は生じないので変換して計算するというアプローチを取ります。
decimal.jsを使います。
インストール
es5を内部で使っているのでes5-shimをいれておきます。
bower install es5-shim
bower install "decimal.js"
上から順番にincludeしてください。
使ってみる
0.1 * 0.2をchromeで実行すると
0.020000000000000004
となります。
これをDecimalを使ってやると0.02でちゃんと出力してくれます。
var a = new Decimal(0.1);
var b = new Decimal(0.2);
out = a.times(b).toNumber();
速度についても調べてみました。
- ブラウザ Chrome
- OS Yosemite 10.10
decimalJS: 4385.760ms
number: 2881.052ms
chromeの中でいい感じに解釈してそうな感もありますが、
思ったより遅くなかったです。
古いブラウザだともっと差がでそうな気もしますが。
検証ソース
(function () {
var out;
var a, b, c, d;
a = new Decimal(0.1);
console.time("decimalJS");
for (var i=0;i < 100000;i++)
{
b = new Decimal(Math.random().toFixed(2));
out = a.times(b).toNumber();
$("#co").append(out + " ");
}
console.timeEnd("decimalJS");
c = 0.1;
console.time("number");
for (var i=0;i < 100000;i++)
{
d = Math.random().toFixed(2);
out = c * d;
$("#co").append(out + " ");
}
console.timeEnd("number");
}());