JavaScriptの数値は「double型にint型を併せ持った型」で表現される

数値を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に丸められる

 

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

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

Related Posts