2012intJavaScriptNumberはじめまして。整数化JavaScriptで小数を整数に直すとき、数学関数を使ってMath.floor(x)と書くことによって整数にすることができます。これよりもっと短く、x|0のように論理演算を用いて書くことによっても整数にすることができます。"|"という演算子はビット単位OR演算子と呼ばれ、ビット毎の論理和を求めることができます。0との論理和はどんな数(といっても0か1しかありませんが...)についても元の数が返ってくるため、論理和をxのビット毎に求めたらxが返ってくるのです。10進数の(x=)13という数字は2進数では1101と表されるので、以下のように1011が求められます。1この場合、xは自然数ですが、xが1.5のような小数の場合、小数点以下が自動的に切り捨てられるため、整数化ができるのです。落とし穴その1ここで、xとして非常に大きい数を入力してみましょう。0x200000006;これは以下の10進数を16進数で表記したものです。8589934598さて、ここで冒頭のx|0という式を実行すると、6となります。85億という大きな数を入力したのに、なぜこんなに小さい値になってしまうのでしょうか。それは、JavaScriptの論理演算は、32ビットの整数として計算するからです。小数点だけでなく、32ビットで表現できる範囲を超えた部分の数値は無視されてしまいます。0先ほどのx|0に加えて、以下の論理式はすべて同じ結果になります。x&(-1)x^0~~xx<<0x>>0また、本来は文字列に対しての関数ですが、parseInt(x)でも整数化ができます。parseIntでは32ビット化はされませんが、一旦文字列オブジェクトに変換してから評価されるので、思いがけない結果になる場合があります(parseInt(3e+50)→3など)。落とし穴その2他の言語では整数型としてintやlong、浮動小数点数型としてfloatやdoubleなどが用意されていますが、JavaScriptにおいては数値を表すのにNumberのみを用います。先述のように論理演算は32ビットの整数として扱われていますが、実際はもっと大きな数も格納できます。32ビットより大きい数を格納できるかというと、Number型の変数に入っているのは64ビット浮動小数点数だからです。「小数」といっても、所詮は2進数で32ビットで表せる整数は完全に内包しているのです。以下のような式で、先頭ビットが1で残り53桁が0の数が得られます。(Math.pow(2,53)).toString(2);"100000000000000000000000000000000000000000000000000000"しかし、それに1を足した数も同じ数になってしまいます。(Math.pow(2,53)+1).toString(2);"100000000000000000000000000000000000000000000000000000"本当は"100000000000000000000000000000000000000000000000000001"になるはずです。浮動小数点数では、以下の形式で数を表現しています。2pk(仮数部と呼ばれる)は52ビット(表現上は53ビット)の2進数を1以上2未満になるように割った数、p(指数部)は11ビットの2進数です。pはそれぞれ以下の2進数になります。k=1.00000000000000000000000000000000000000000000000000001p=110101(=5310)pは充分表現範囲内に収まっているのですが、kの桁数が52を超えているので、ここで表現範囲を超えてしまい、最下位ビットが丸められてしまうのです。入力してチェックしてみてください。SocialAnimationinfomisc.当サイトは、ブラウザのJavaScript設定を有効にしてご覧ください。