JavaScriptの数値はdouble型で表現される

数値を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
  

いくつもの計算を続けて行えば、これらの丸め誤差が積み重なり、精度はどんどん低下してしまいます。