2009年05月22日 15:00 [Edit]
javascript - には整数はない
違います。
javascriptで整数の変数を強制的に符号なし整数に変換する方法 ? kujavascriptの整数は内部的には32bit intで扱われていて(Firefox3.1, Chrome0.2の場合)、演算の結果が0×80000000を超えると自動的に負の値になります。
事実はもっと驚くべきものです。
以下をご覧下さい。
puts = make_puts(document.getElementById('ttyp0'));
for (var n = 1; n <= 54; n++){
puts(2, '**', n, ' - 1 = ', Math.pow(2, n) - 1);
}
2の32乗どころか、2の53乗まできちんと計算できていますが、54乗になったとたん、数字が変です。奇数でなければならないのに偶数になっています。
なぜこんなことになるかといえば、JavaScriptのNumberオブジェクトは、数値を常に浮動小数点で保持しているからです。そうなのです。JavaScriptには整数がないんです。整数が「ある」ように見えているのは、文字列にする時に小数点がないだけなのです。
ECMAScript Language Specification (HTML version)4.3.20 Number Type
The type Number is a set of values representing numbers. In ECMAScript, the set of values represents the double-precision 64-bit format IEEE 754 values including the special "Not-a-Number" (NaN) values, positive infinity, and negative infinity.
確かにこれなら、整数が32bitではなく53bitまである理由も納得が行きます。
それでは、なぜ以下は「期待通り」に動くのでしょうか?
puts = make_puts(document.getElementById('ttyp1'));
for (var n = 1; n <= 54; n++){
puts('(1', '<<', n, ') - 1 = ', (1 << n) - 1);
}
それは、ビット演算の時のみ、内部的に32bit整数に変換してから、演算が終わった後また浮動小数点に戻しているからです。C的にいえば、一旦 signed int にキャストしているだけなのです。
Arrayオブジェクトが実は配列ではなく、数値をキーとするただのオブジェクトなのと同様、JavaScriptにはこうした「あるように見せかけているけど、実はない」という落とし穴が結構あって、むしろ中級者以上ほどはまりやすいように感じます。
Dan the JavaScripter
Auxiliary Codes
make_puts = function(el){
return function(){
for (var i = 0, l = arguments.length; i < l; i++){
el.appendChild(document.createTextNode(arguments[i]));
}
el.appendChild(document.createElement('br'));
}
};
Posted by dankogai at 15:00│Comments(1)│TrackBack(0)
この記事へのトラックバックURL
この記事へのコメント
「整数」と「整数型」は混乱する初心者も多いので、「整数型はない」として頂いた方が良いかと…
1.0は「整数」ですから。IEEE doubleで表現されていたとしても。
1.0は「整数」ですから。IEEE doubleで表現されていたとしても。
Posted by shiro at 2009年05月22日 17:44