JavaScriptで負数を2進数や16進数で表現したい

値を2進数や16進数で表示する場合は toString(n) を使用します。

let d = 45;
let b = d.toString(2) // "101101"
let h = d.toString(16) // "2d"

しかし、値が負数だとうまくいきません。整数部を16進数で表現してから負号”-“が追記されてしまいます。

let d = -45;
let b = d.toString(2) // "-101101"
let h = d.toString(16) // "-2d"

「負数」を2進数/16進数で表現する

負数を2進数/16進数で表現したい場合には、負数を「2の補数」で表現するようにします。

2の補数とは値をビット反転させて1を加えたもので、負数をビットで表現するために使われます。

例えば-45の場合は、整数部”45″の2の補数を求めることでビットで表現できます。

00101101 (“45″の2進数表現) → 11010010 (ビット反転) → 11010011(1を加える)

JavaScriptで負数を2の補数で表現するには、符号なし右シフト演算子を使って「負数 >>> 0」とします。

let d = -45 >>> 0; // 負数を2の補数で表現
let b = d.toString(2) // "11111111111111111111111111010011"
let h = d.toString(16) // "ffffffd3"

JavaScriptは整数32ビットなので上位ビットは1やfで埋まりますが、最下位8ビットを見ると手計算の結果と一致していることがわかります。

また16進数の場合も、2の補数できちんと表現されていることが確認できます。

「2の補数」を2進数/16進数で表現する

先ほど2の補数は「ビットを反転して1を加える」と説明しました。

JavaScriptではチルダ演算子(~)を使うと値をビット反転させることができます。それに1を加えれば「2の補数」を求めることができます。

let d = 45;
let b = (~d+1 >>> 0).toString(2); // "11111111111111111111111111010011"
let h = (~d+1 >>> 0).toString(16); // "ffffffd3"

「負数 = 整数部の2の補数」なので、結果は”負数を2進数/16進数で表現する”場合と同じになります。

Related Posts