JavaScriptで整数をバイナリに変換するにはどうすればよいですか?


299

正または負の整数を2進数で表示したいのですが。

むしろこの質問のようですが、JavaScript用です。


2
a.toString(2)の例は-1では機能しないようです
barlop

1
2進数から10進数に変換することもできます。stackoverflow.com
Anderson Green

そして、私が「バイナリで」と言ったとき、それは少しあいまいかもしれません。つまり、2の補数である内部ビット文字列表現であるため、正の数は2を底とし、先頭に0が付きます(負の数は、マイナス記号や符号の大きさの表現ではなく、それらの正の等価の関数)
barlop

回答:


499
function dec2bin(dec){
    return (dec >>> 0).toString(2);
}

dec2bin(1);    // 1
dec2bin(-1);   // 11111111111111111111111111111111
dec2bin(256);  // 100000000
dec2bin(-256); // 11111111111111111111111100000000

Number.toString(2)関数を使用できますが、負の数を表すときにいくつかの問題があります。たとえば、(-1).toString(2)出力は"-1"です。

この問題を解決するには、符号なし右シフトビット演算子(>>>)を使用して、数値を符号なし整数に強制変換します。

実行(-1 >>> 0).toString(2)すると、数値を0ビット右にシフトします。これにより、数値自体は変更されませんが、符号なし整数として表されます。上記のコードは"11111111111111111111111111111111"正しく出力されます。

この質問にはさらに説明があります。

-3 >>> 0 (右論理シフト)は、引数を符号なし整数に強制変換します。これが、32ビットの2の補数表現-3を取得する理由です。



JavaScriptを試してからしばらく経ったが、ここで試してみたw3schools.com/js/tryit.asp?filename=tryjs_output_alert この<script> window.alert((-3 >>> 0).toString(2)); </ script>ええ、それはうまくいった
barlop 2015

1
テキストから入力を取得しているため、toString(2)は機能しません。これを使用してください:function decToBase(dec、base){return parseInt(dec).toString(base); } alert(decToBase(dec、2));
メイガス

あなたは入力がテキストであると想定していますが、答えの関数は整数を期待しています...したがって、入力がテキストの場合はそれを整数に変換するだけで、偽のビットシフトを使用してそれを行います
fernandosavio

テキストから入力を取得している@Magus ?!
Barlop 2015年

207

試す

num.toString(2);

2は基数であり、2から36までの任意の基数を指定できます

ここにソース

更新:

これは正の数に対してのみ機能します。JavaScriptは負の2進整数を2の補数表記で表します。私はトリックを行うべきこの小さな関数を作りました、私はそれを適切にテストしていません:

function dec2Bin(dec)
{
    if(dec >= 0) {
        return dec.toString(2);
    }
    else {
        /* Here you could represent the number in 2s compliment but this is not what 
           JS uses as its not sure how many bits are in your number range. There are 
           some suggestions /programming/10936600/javascript-decimal-to-binary-64-bit 
        */
        return (~dec).toString(2);
    }
}

ここから助けてもらいまし


-1では機能しません。a = -1; document.write(Number(a.toString(2))); ディスプレイ-1
barlop

アップデートはまだ負の数(のための仕事には表示されません-3戻ります1)。また、私は、少なくとも0を修正するdec > 0必要があると考えています。dec >= 0dec2Bin(0)10
アダムメリフィールド2014

上記のコメントのどちらの場合も、Chromeコンソールで正しい結果が返されます-var a = -1; a.toString(2); "-1" var a = -3; a.toString(2); 「-11」
Anmol Saraf 14

@AnmolSaraf私はあなたが何を意味するかを理解しています、そして口語的に人々が10進数で-5であるものを言うとき、そして答えは-5です。 101と-5は-101ですが、コンピューターはマイナス記号を格納しないため、1と0を表すだけなので、負の数を2進数で言う場合、負の数(マイナス記号を含む)を1と0に入れることを意味します。いくつかの方法には、1の補数、2の補数、および「符号と大きさ」が含まれます。したがって、-101010101や-0101010は、2進数の負の数によって意味されるものではありません。
barlop 2015

このリンクは、一部のstackoverflow.com/questions/12337360/…に関係している可能性があります。とにかく、あなたの答えはそれ自体と矛盾します。「JavaScriptは負の2進整数を2の補数表記で表します。」そして、あなたのコードは、「ここでは2の賛辞で数を表すことができますが、これはJSが[ナンセンスな理由]として使用するものではありません。
barlop

53

「バイナリに変換」のバイナリは、主に3つのことを指します。位置番号システム、メモリ内のバイナリ表現または32ビットのビット文字列。(64ビットのビット文字列については、Patrick Robertsの回答を参照してください)

1.番号システム

(123456).toString(2)数値を基数2の位置数値システムに変換します。このシステムでは、負の数は、10進数と同じようにマイナス記号で書き込まれます。

2.内部表現

数値の内部表現は64ビット浮動小数点であり、この回答ではいくつかの制限について説明します。JavaScriptでこれのビット文字列表現を作成したり、特定のビットにアクセスしたりする簡単な方法はありません

3.マスクとビットごとの演算子

MDNには、ビットごとの演算子がどのように機能するかについての概要がわかります。重要なこと:

ビット演算子は、オペランドを32ビットのシーケンス(0と1)として扱います。

操作が適用される前に、64ビットの浮動小数点数が32ビットの符号付き整数にキャストされます。それらが元に戻された後。

以下は、数値を32ビット文字列に変換するためのMDNサンプルコードです。

function createBinaryString (nMask) {
  // nMask must be between -2147483648 and 2147483647
  for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
  return sMask;
}

createBinaryString(0) //-> "00000000000000000000000000000000"
createBinaryString(123) //-> "00000000000000000000000001111011"
createBinaryString(-1) //-> "11111111111111111111111111111111"
createBinaryString(-1123456) //-> "11111111111011101101101110000000"
createBinaryString(0x7fffffff) //-> "01111111111111111111111111111111"

単純なNumber(num).toString(2)を使用する代わりにこの関数を使用する利点は何ですか?
Magus

5
@Magus私は数字とバイナリ文字列の違いを適切に説明していると思います。32ビットのバイナリ文字列は、常に「1」と「0」で構成される32文字の長さです。toStringは、指定された基数で位置番号システムを使用して表された実際の数値を返します。文字列が必要な理由によって異なりますが、意味が大きく異なります。
AnnanFay

申し訳ありませんが、あなたは正しいです。コードに直接ジャンプしました。
Magus

1
他の投稿されたメソッドを使用して先頭の0に問題がありました(特にこの番号536870912では、2つの先頭の0が削除されています)が、このソリューションはそれを正しく処理しました。
UberMouse 2015

@UberMouseええ>>>の先頭に0の問題があるので、これを受け入れます。
Barlop 2017

43

簡単な方法はただ...

Number(42).toString(2);

// "101010"

24
私が好む(42).toString(2)
Willem D'Haeseleer 14

33
またはさらに短い42..toString(2)
kapex 2014

9
人々はこれに苦しんでいます。答えは正解です。入力(42)を整数にキャストし、その行が必要だからです。テキスト入力から「数値」を取得した場合、toString(2)は機能しません。
Magus

4
@Kapep、おい、それは天才だ。どうやってそれを知ったの?
パセリエ2017

2
@BatuG。数値の構文では、小数点記号の後の部分を省略できます。1.と同じ1.0か、まったく同じように書くことができます1(同様に、前の部分を省略して、の.5代わりに書くこともできます0.5)。したがって、この例では、最初のドットは数値の一部である小数点記号であり、2番目のドットはその数値でメソッドを呼び出すためのドット演算子です。2つのドットを使用する必要があります(または括弧で数値を囲む)。42.toString(2)パーサーはドットを小数点として認識し、ドット演算子がないためにエラーをスローするため、単に書き込むことはできません。
kapex 2018

30

この回答は、2147483648 10(2 31)〜9007199254740991 10(2 53 -1)の範囲の絶対値を持つ入力に対処しようとします。


JavaScriptでは、数値は64ビットの浮動小数点表現で格納されますが、ビット単位の演算では2の補数形式の32ビット整数強制変換されるため、ビット単位の演算を使用するアプローチでは、出力の範囲が-2147483648 10(-2 31)に制限されます。– 2147483647 10(2 31 -1)。

ただし、ビット単位の演算が回避され、64ビットの浮動小数点表現が数学的演算のみを使用して保持される場合、53ビットを符号拡張することにより、安全な整数を64ビットの2の補数のバイナリ表記に確実に変換できますtwosComplement

function toBinary (value) {
  if (!Number.isSafeInteger(value)) {
    throw new TypeError('value must be a safe integer');
  }

  const negative = value < 0;
  const twosComplement = negative ? Number.MAX_SAFE_INTEGER + value + 1 : value;
  const signExtend = negative ? '1' : '0';

  return twosComplement.toString(2).padStart(53, '0').padStart(64, signExtend);
}

function format (value) {
  console.log(value.toString().padStart(64));
  console.log(value.toString(2).padStart(64));
  console.log(toBinary(value));
}

format(8);
format(-8);
format(2**33-1);
format(-(2**33-1));
format(2**53-1);
format(-(2**53-1));
format(2**52);
format(-(2**52));
format(2**52+1);
format(-(2**52+1));
.as-console-wrapper{max-height:100%!important}

古いブラウザでは、次の関数と値にポリフィルが存在します。

追加のボーナスとして、次を使用して⌈64/ log 2(基数)桁の負の数値に対して2の補数変換を実行する場合、任意の基数(2〜36)をサポートできますBigInt

function toRadix (value, radix) {
  if (!Number.isSafeInteger(value)) {
    throw new TypeError('value must be a safe integer');
  }

  const digits = Math.ceil(64 / Math.log2(radix));
  const twosComplement = value < 0
    ? BigInt(radix) ** BigInt(digits) + BigInt(value)
    : value;

  return twosComplement.toString(radix).padStart(digits, '0');
}

console.log(toRadix(0xcba9876543210, 2));
console.log(toRadix(-0xcba9876543210, 2));
console.log(toRadix(0xcba9876543210, 16));
console.log(toRadix(-0xcba9876543210, 16));
console.log(toRadix(0x1032547698bac, 2));
console.log(toRadix(-0x1032547698bac, 2));
console.log(toRadix(0x1032547698bac, 16));
console.log(toRadix(-0x1032547698bac, 16));
.as-console-wrapper{max-height:100%!important}

を使用しArrayBufferてa Float64Arrayとaの和集合を作成した私の古い回答に興味がある場合Uint16Arrayは、この回答の変更履歴を参照してください。


ありがとう、これが64ビットで動作するのは良いことです。アンナンの答えに対するこの答えの利点を教えていただけますか?
barlop

2
はるかに広い範囲?それは、アンナンの答えを好きになるだけで-(2**53)-12**53-1なく、のために働きます。-(2**31)2**31-1
パトリックロバーツ

はい、それは大きなアドバンテージです。私はそれを取得します。それはかなり多くのコードですが、私が意味したことは、他のアドバンテージがあるかどうか知りたいですか?
barlop

1
2 ** 32 + 1以降、最後(右端)のビットは、設定する必要があるときにクリアされます。
Lovro 2018年

1
行が次の場合に機能します:var exponent =((uint16 [3]&0x7FF0)>> 4)-1023 + 1;
Lovro 2018年

15

32ビットの場合は問題ありませんが、この答えの最後にあるのは、developer.mozilla.org(MDN)からのコードですが、A)フォーマットおよびB)チェックのためにいくつかの行が追加されています。数値は範囲内です。

x.toString(2)ネガティブには機能しないという提案もありますが、マイナス記号が表示されているだけで、良くありません。

フェルナンド氏は、(x>>>0).toString(2);ネガティブには問題のない簡単な解決策について言及しましたが、xが正の場合にはわずかな問題があります。1で始まる出力があり、正の数の場合は2の補数として適切ではありません。

2の補数で0から始まる正の数と1で始まる負の数の事実を理解していない人は、2の補数でこのSO QnAをチェックできます。「2の補数」とは何ですか?

解決策は、正の数の前に0を付加することです。これは、この回答の以前のリビジョンで行いました。また、33ビットの数値を受け入れることもできますし、変換する数値が-(2 ^ 31)<= x <2 ^ 31-1の範囲内であることを確認することもできます。したがって、数値は常に32ビットです。しかし、そうするのではなく、mozilla.orgのこのソリューションを使用できます

Patrickの回答とコードは長く、64ビットで動作するようですが、コメンターが発見したバグがあり、コメンターはpatrickのバグを修正しましたが、patrickはコードに「マジックナンバー」があり、コメントしていません。忘れてパトリックは自分のコードを完全に理解しなくなりました/それがなぜ機能するのか

アナンは不正確で不明確な用語をいくつか持っていましたが、developer.mozilla.orgによる解決策について言及しましたhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators これは32ビットの数値で機能します。

コードはかなりコンパクトで、3行の関数です。

しかし、出力を8ビットのグループにフォーマットするための正規表現を追加しました。基づいて、JavaScriptで桁区切りとしてカンマで番号を印刷する方法 (私だけでそれをグループ化するからそれを改正3S右、左と追加にカンマでグループ化し、8S右から左へ、そして追加のスペースを

そして、モジラはnMask(入力された数)のサイズについてコメントしましたが、範囲内である必要がありますが、数が範囲外の場合はテストもエラーもスローしなかったため、と付け加えた。

彼らがなぜそれらのパラメーターを 'nMask'と名付けたのかは分かりませんが、それはそのままにしておきます。

リファレンス:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators

function createBinaryString(nMask) {
  // nMask must be between -2147483648 and 2147483647
  if (nMask > 2**31-1) 
     throw "number too large. number shouldn't be > 2**31-1"; //added
  if (nMask < -1*(2**31))
     throw "number too far negative, number shouldn't be < 2**31" //added
  for (var nFlag = 0, nShifted = nMask, sMask = ''; nFlag < 32;
       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
  sMask=sMask.replace(/\B(?=(.{8})+(?!.))/g, " ") // added
  return sMask;
}


console.log(createBinaryString(-1))    // "11111111 11111111 11111111 11111111"
console.log(createBinaryString(1024))  // "00000000 00000000 00000100 00000000"
console.log(createBinaryString(-2))    // "11111111 11111111 11111111 11111110"
console.log(createBinaryString(-1024)) // "11111111 11111111 11111100 00000000"


8

ビットの配列を返す独自の関数を作成できます。数値をビットに変換する方法の例

除数| 配当| ビット/残り

2 | 9 | 1

2 | 4 | 0

2 | 2 | 0

〜| 1 |〜

上記の行の例:2 * 4 = 8、残りは1なので、9 = 1 0 0 1

function numToBit(num){
    var number = num
    var result = []
    while(number >= 1 ){
        result.unshift(Math.floor(number%2))
        number = number/2
    }
    return result
}

残りを下から上に読みます。中央から上に1桁目。


1
ところで、なぜあなたのMath.floor(number%2)代わりにnumber = Math.floor(number/2)
パセリエ2017

1
その理由は、number%2がnumber / 2と等しくないためです。商ではなく残りに興味があります。
supritshah1289

0

私はこれを行う何かを思いつくために別のアプローチを使用しました。私のプロジェクトではこのコードを使用しないことにしましたが、誰かに役立つ場合に備えて、関連性のある場所に残しておくと思いました。

  • ビットシフトや2の補数強制を使用しません。
  • 出てくるビット数を選択します(「8」、「16」、「32」の有効な値をチェックしますが、変更できると思います)
  • 符号付き整数として処理するか、符号なし整数として処理するかを選択します。
  • 符号付き/符号なしとビット数の組み合わせを指定して範囲の問題をチェックしますが、エラー処理を改善する必要があります。
  • また、ビットをintに変換する「リバース」バージョンの関数もあります。この出力を解釈するものはおそらく他にないので、それが必要になります:D

function intToBitString(input, size, unsigned) {
	if ([8, 16, 32].indexOf(size) == -1) {
		throw "invalid params";
	}
	var min = unsigned ? 0 : - (2 ** size / 2);
        var limit = unsigned ? 2 ** size : 2 ** size / 2;
	if (!Number.isInteger(input) || input < min || input >= limit) {
		throw "out of range or not an int";
	}
	if (!unsigned) {
		input += limit;
	}
	var binary = input.toString(2).replace(/^-/, '');
	return binary.padStart(size, '0');
}

function bitStringToInt(input, size, unsigned) {
	if ([8, 16, 32].indexOf(size) == -1) {
		throw "invalid params";
	}
	input = parseInt(input, 2);
	if (!unsigned) {
		input -= 2 ** size / 2;
	}
	return input;
}


// EXAMPLES

var res;
console.log("(uint8)10");
res = intToBitString(10, 8, true);
console.log("intToBitString(res, 8, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, true));
console.log("---");

console.log("(uint8)127");
res = intToBitString(127, 8, true);
console.log("intToBitString(res, 8, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, true));
console.log("---");

console.log("(int8)127");
res = intToBitString(127, 8, false);
console.log("intToBitString(res, 8, false)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, false));
console.log("---");

console.log("(int8)-128");
res = intToBitString(-128, 8, false);
console.log("intToBitString(res, 8, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 8, true));
console.log("---");

console.log("(uint16)5000");
res = intToBitString(5000, 16, true);
console.log("intToBitString(res, 16, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 16, true));
console.log("---");

console.log("(uint32)5000");
res = intToBitString(5000, 32, true);
console.log("intToBitString(res, 32, true)");
console.log(res);
console.log("reverse:", bitStringToInt(res, 32, true));
console.log("---");


-1

もう一つの選択肢

const decToBin = dec => {
  let bin = '';
  let f = false;

  while (!f) {
    bin = bin + (dec % 2);    
    dec = Math.trunc(dec / 2);  

    if (dec === 0 ) f = true;
  }

  return bin.split("").reverse().join("");
}

console.log(decToBin(0));
console.log(decToBin(1));
console.log(decToBin(2));
console.log(decToBin(3));
console.log(decToBin(4));
console.log(decToBin(5));
console.log(decToBin(6));

ヴィンセントの回答とコメントをご覧ください。投稿にも適用されます
barlop

これは、彼の回答にコメントで投稿されたもので、意見の不一致はなく、他の人からの同意もあり、「コンピュータサイエンスを研究して自分で行う方法を確認し、自分自身で教えるには役立つかもしれませんが、それは私が行うことではありません。あなたがそのように手動で行うホイールを再発明するつもりなら、それは少なくとも効率の向上または対応できる値のサイズの増加のようないくつかの利点があるはずです。私にはわかりませんそこにそのような利点を述べているあなたからの議論。」
barlop

さらに、あなたのソリューションは完全に失敗し、それが正の数は、1から始まり、完全に負の数のために失敗し、私の質問は、正または負の言及になり
barlopを

だからあなたの「答え」は多くのレベルで間違っています。回答を投稿する前に、常に他の回答を確認する必要があります
barlop

-2

これは私のコードです:

var x = prompt("enter number", "7");
var i = 0;
var binaryvar = " ";

function add(n) {
    if (n == 0) {
        binaryvar = "0" + binaryvar; 
    }
    else {
        binaryvar = "1" + binaryvar;
    }
}

function binary() {
    while (i < 1) {
        if (x == 1) {
            add(1);
            document.write(binaryvar);
            break;
        }
        else {
            if (x % 2 == 0) {
                x = x / 2;
                add(0);
            }
            else {
                x = (x - 1) / 2;
                add(1);
            }
        }
    }
}

binary();

3
自分で教えるために、コンピュータサイエンスを手動で行う方法を確認するのに役立ちますが、それは私が求めていることではありません。そのように手動で行うホイールを再発明する場合は、少なくとも、効率が向上する利点、または処理できる値のサイズが増加するなどの利点があるはずです。そこにそのような利点があることを述べているあなたからの議論を見ることはありません。
barlop 2017年

-3

これが解決策です。実際には非常に単純です

function binaries(num1){ 
        var str = num1.toString(2)
        return(console.log('The binary form of ' + num1 + ' is: ' + str))
     }
     binaries(3

)

        /*
         According to MDN, Number.prototype.toString() overrides 
         Object.prototype.toString() with the useful distinction that you can 
         pass in a single integer argument. This argument is an optional radix, 
         numbers 2 to 36 allowed.So in the example above, we’re passing in 2 to 
         get a string representation of the binary for the base 10 number 100, 
         i.e. 1100100.
        */

1
そのソリューションはすでに何度も提案されており、OPが2012年3月30日にすでに9:01にコメントしているように、負の数では機能しません。
エイドリアンW

@AdrianW私はこれに反対投票することをお勧めします。私はあなたがそうしていないことに気づきます。そのとき、あなたが回答に反対票を投じるには何が必要ですか?
barlop
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.