SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 採用情報 ...

double, floatとdecimalの違い

問題

float, double と decimal の違いが判りません。

どちらも小数で同じなのでは?

答え

double、float は10進数の小数を2進数の小数で表現した近似値。
お金の計算などには使えない。

10進数の小数を有限桁の2進数の小数では表現できないことが多い。

10進数はこんな数
← 1000の位、100の位、10の位、1の位、1/10の位、1/100の位、1/1000の位 →

2進数はこんな数
← 8の位、4の位、2の位、1の位、1/2の位、1/4の位、1/8の位 →

10進数の0.5は、2進数の0.1
(0.5=1/2や0.25=1/4、0.75=3/4などはきれいに表現できる)

10進数の0.05は、2進数の0.0000110011001100110011001100…
(0/2+0/4+0/8+0/16+1/32+1/64+0/128+0/256+1/512+1/1024+… 2進数では無限小数)

無限小数を有限桁で切ると誤差が出る = double, float。

これを掛けたり足したりしていくとやっぱり誤差は出る。

誤差が出ないように10進数の小数として扱うのがdecimal。

メモ

2進数の小数の近似値っぷりは、JavaScriptで簡単に確認できる。

これを見れば、floatは金額計算などには怖くて使えない。

var a=15; a.toString(2);
// 1111 Number.toString(2)で2進数にできる

11.11.toString(2);
// "1011.0001110000101000111101011100001010001111010111"

0.1.toString(2);
// "0.0001100110011001100110011001100110011001100110011001101"

0.125.toString(2);
// "0.001" これは有限桁に収まった

0.126.toString(2);
// "0.00100000010000011000100100110111010010111100011010101"

0.128.toString(2);
// "0.00100000110001001001101110100101111000110101001111111"

0.15.toString(2);
// "0.0010011001100110011001100110011001100110011001100110011"

0.0001.toString(2);
// "0.000000000000011010001101101110001011101011000111000100001100101101"

関連するメモ

コメント