数値をtypeofで調べると整数も小数も数値型(number)として判定されます。
typeof(123); // "number"
typeof(123.456); // "number"
他の言語ではintやfloat型といったように数値型が複数存在し、型の役割が明確です。
ではJavaScriptの”number”とは何を表すのでしょうか?
すべての数が倍精度浮動小数点数
ECMAScript標準仕様によると、JavaScriptのnumber型は倍精度の浮動小数点数(double型)で表現されます。
整数型は存在しません。
ただし、double型は整数を53ビットの精度まで完璧に表現することができます。
“-9,007,199,254,740,992″から”9,007,199,254,740,992″までですね
これらの範囲を超えた整数は丸められます。
console.log(9007199254740992); // 9007199254740992
console.log(9007199254740993); // 9007199254740992に丸められる
console.log(-9007199254740992); // -9007199254740992
console.log(-9007199254740993); // -9007199254740992に丸められる
つまり、JavaScriptのnumberは「double型とint型を併せ持った型」で表現されるのです。
numberの正体はわかりましたが、JavaScriptで数を扱う上では、以下の性質も理解しておくとよいでしょう。
ビット演算は整数に変換される
JavaScriptでビット演算を実行する際には、暗黙のうちに32ビットの整数に変換されます。
例えばビット反転を行う「チルダ演算子」を2回使うと小数を整数化できるのですが、これはこの性質をうまく利用しています。
console.log(~~1.23) // 1
console.log(~1.23) // -2 (整数化した"1"に対してビット反転)
console.log(~-2) // 1
浮動小数点数演算における演算誤差
浮動小数点演算によって得られる演算は、常に正しい結果が得られるとは限りません。
実際の計算は2進数で計算するため、表現できる最も近い実数へと丸められます。
(0.1+0.2)+0.3 // 0.6000000000000001
0.1+(0.2+0.3) // 0.6
いくつもの計算を続けて行えば、これらの丸め誤差が積み重なり、精度はどんどん低下してしまいます。