先日、WEBツールでIPアドレスをソートするツールを作った際、JavaScriptでビット演算する際、正の数を期待していたのに結果が負の数となってしまいました。
とはいえちゃんとリファレンスには書かれているので悩むほどではなかったのですが・・・。
とりあえずJavaScriptのビット演算でunsignedを期待するとバグをの元になるという話です。
では本題。
乗算をするなら、特に組み込みエンジニアならビット演算を検討する事もあろうかと思いますが、JavaScriptでビット演算した時何が起こるか。という話です。
私も組み込みから入った人間なのでまずそっちに行っちゃうんですよね・・・。
例えばですが、以下のように24ビット左シフトする関数があったとします。
1 2 3 |
function bit_shift24(value) { function value = << 24; } |
それに対して例えばC言語で(明示的に型宣言をする言語なら他の言語でも同様かと思います)
1 2 3 |
unsigned int bit_shift24(value) { return value << 24; } |
とするとします。
処理している内容は一見一緒です。違う点は戻り値の型が明示的に宣言できるか否かという点です。
私はここでしくりました。
JavaScriptはこのbit演算の結果は符号ありintとして扱います。いきなり負数として扱われて、「あ”ー!」ってなりました。
明示的に型指定していないので当然なのですが・・・。
なのでもし、ビットシフトした結果を符号なしの整数値で扱いたいなら以下の様なコードが必要です。
1 |
(value << 24) >>> 0 |
※ 演算子の優先順位からしてカッコなしでも構いません。
肝となるのは「>>>」の部分です。
これはJavaScriptにおいて”符号なし”右ビットシフトの意味になり、式の値がunsignedとなります。
もしかしたらunsignedにキャストする方法もあるもしれませんが、個人的にはこれで解決できたので良しとしています。
思い込みでコーディングしてるとミスるよ!っていう典型でした。
あとがきですが、JavaScriptに通じてる方からちゃんとリファレンスくらい読めよ!アホかよ!って声が聞こえてくる気がします・・・。
仰るとおりです・・・すいません・・・おゆるじぐだじゃい・・・(白目)
そういえばJavaScriptで符号なし/ありで使われるオブジェクトをtype ofしてみたら両方numberのようですね。
プリミティブではないので同じ型だろうが表現できれば良いのでしょうけど、符号有りなのか無しなのか確認できないのはなんとなく気持ち悪いですね。
それとも確認する方法があるのでしょうか。
気が向いたら調べます。まる。