簡體   English   中英

如何在 JavaScript 中將整數轉換為二進制?

[英]How do I convert an integer to binary in JavaScript?

我想以二進制形式查看整數,正數或負數。

很喜歡這個問題,但是對於 JavaScript。

 function dec2bin(dec) { return (dec >>> 0).toString(2); } console.log(dec2bin(1)); // 1 console.log(dec2bin(-1)); // 11111111111111111111111111111111 console.log(dec2bin(256)); // 100000000 console.log(dec2bin(-256)); // 11111111111111111111111100000000

您可以使用Number.toString(2)函數,但它在表示負數時會出現一些問題。 例如, (-1).toString(2)輸出為"-1"

要解決此問題,您可以使用無符號右移位運算符 ( >>> ) 將您的數字強制為無符號整數。

如果您運行(-1 >>> 0).toString(2)您會將數字 0 向右移動,這不會更改數字本身,但它將表示為無符號整數。 上面的代碼將正確輸出"11111111111111111111111111111111"

這個問題有進一步的解釋。

-3 >>> 0 (右邏輯移位)將其參數強制轉換為無符號整數,這就是為什么您會得到 -3 的 32 位二進制補碼表示。

嘗試

num.toString(2);

2 是基數,可以是 2 到 36 之間的任何基數

來源這里

更新:

這僅適用於正數,Javascript 以二進制補碼表示法表示負二進制整數。 我做了這個應該可以解決問題的小功能,但我沒有正確測試它:

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 https://stackoverflow.com/questions/10936600/javascript-decimal-to-binary-64-bit 
        */
        return (~dec).toString(2);
    }
}

我從這里得到了一些幫助

一個簡單的方法就是...

Number(42).toString(2);

// "101010"

“轉換為二進制”中的二進制可以指三個主要內容。 位置數字系統,內存中的二進制表示或 32 位位串。 (對於 64 位位串,請參閱Patrick Roberts 的回答

1. 數制

(123456).toString(2)將數字轉換為以 2 為底的位置數字系統 在這個系統中,負數用減號寫成,就像十進制一樣。

2. 內部代表

數字的內部表示是64 位浮點數,在這個答案中討論了一些限制。 沒有簡單的方法可以在 javascript 中創建它的位串表示,也沒有訪問特定位的簡單方法。

3. 掩碼和位運算符

MDN 很好地概述了按位運算符的工作原理。 重要的:

按位運算符將其操作數視為32 位(零和一)的序列

在應用操作之前,將 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"

此答案嘗試使用 2147483648 10 (2 31 ) – 9007199254740991 10 (2 53 -1) 范圍內的絕對值來處理輸入。


在 JavaScript 中,數字以64 位浮點表示形式存儲,但按位運算將它們強制轉換為二進制補碼格式的32 位整數,因此任何使用按位運算的方法都將輸出范圍限制為 -2147483648 10 (-2 31 ) – 2147483647 10 (2 31 -1)。

但是,如果避免按位運算並僅使用數學運算保留 64 位浮點表示,我們可以通過對 53 位twosComplement進行符號擴展,將任何安全整數可靠地轉換為 64 位二進制補碼二進制表示法:

 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}

對於較舊的瀏覽器,polyfills 存在以下功能和值:

另外,如果您使用BigInt對 ⌈64 / log 2 (radix)⌉ 數字中的負數執行二進制補碼轉換,則可以支持任何基數 (2–36):

 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}

如果您對我使用ArrayBufferFloat64ArrayUint16Array之間創建聯合的舊答案感興趣,請參閱此答案的修訂歷史

我想采用的解決方案適用於 32 位,是此答案結尾的代碼,來自 developer.mozilla.org(MDN),但添加了一些行用於 A)格式化和 B)檢查數字在范圍內。

一些人建議x.toString(2)不適用於負數,它只是在其中貼一個減號,這不好。

Fernando 提到了(x>>>0).toString(2); 這對於負數很好,但當 x 為正數時有一個小問題。 它的輸出以 1 開頭,對於正數,它不是正確的 2s 補碼。

任何不了解 2s 補碼中以 0 開頭的正數和以 1 開頭的負數這一事實的人都可以在 2s 補碼上檢查此 SO QnA。 什么是“2的補碼”?

一個解決方案可能涉及為正數添加一個 0,我在此答案的早期版本中這樣做了。 有時可以接受 33 位數字,或者可以確保要轉換的數字在 -(2^31)<=x<2^31-1 范圍內。 所以這個數字總是32位。 但是,您可以在 mozilla.org 上使用此解決方案,而不是這樣做

帕特里克的答案和代碼很長,顯然適用於 64 位,但有一個評論者發現的錯誤,評論者修復了帕特里克的錯誤,但帕特里克在他的代碼中有一些“幻數”,他沒有評論並且有忘記了,帕特里克不再完全理解他自己的代碼/它為什么起作用。

Annan 有一些不正確和不清楚的術語,但提到了 developer.mozilla.org 的解決方案

注意 - 舊鏈接https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators現在重定向到其他地方並且沒有該內容但正確的舊鏈接,當archive.org 檢索頁面!,可在此處獲得https://web.archive.org/web/20150315015832/https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators

那里的解決方案適用於 32 位數字。

代碼非常緊湊,三行的函數。

但是我添加了一個正則表達式來格式化輸出,以 8 位為一組。 基於如何在 JavaScript 中將逗號打印為千位分隔符(我只是將其修改為從右到左將其分組為3 秒並添加逗號,以從右到左分組為8 秒並添加空格

而且,雖然 Mozilla 對 nMask 的大小(輸入的數字)發表了評論......它必須在范圍內,但當數字超出范圍時,他們沒有測試或拋出錯誤,所以我已經補充說。

我不確定他們為什么將參數命名為“nMask”,但我會保持原樣。

https://web.archive.org/web/20150315015832/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" //added further console.log example console.log(createBinaryString(2**31 -1)) //"01111111 11111111 11111111 11111111"

您可以編寫自己的函數來返回位數組。 示例如何將數字轉換為位

除數| 股息| 位/余數

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 在中間到頂部。

這就是我設法處理它的方式:

const decbin = nbr => {
  if(nbr < 0){
     nbr = 0xFFFFFFFF + nbr + 1
  }
  return parseInt(nbr, 10).toString(2)
};

從這個鏈接得到它: https ://locutus.io/php/math/decbin/

我們還可以計算正數或負數的二進制,如下所示:

 function toBinary(n){ let binary = ""; if (n < 0) { n = n >>> 0; } while(Math.ceil(n/2) > 0){ binary = n%2 + binary; n = Math.floor(n/2); } return binary; } console.log(toBinary(7)); console.log(toBinary(-7));

您可以使用遞歸解決方案:

 function intToBinary(number, res = "") { if (number < 1) if (res === "") return "0" else return res else return intToBinary(Math.floor(number / 2), number % 2 + res) } console.log(intToBinary(12)) console.log(intToBinary(546)) console.log(intToBinary(0)) console.log(intToBinary(125))
僅適用於正數。

我想以二進制形式查看整數,正數或負數。

這是一個老問題,我認為這里有很好的解決方案,但沒有解釋如何使用這些聰明的解決方案。

首先,我們需要了解一個數字可以是正數或負數。 此外,JavaScript 提供了一個值為9007199254740991MAX_SAFE_INTEGER常量。 該數字背后的原因是 JavaScript 使用IEEE 754中指定的雙精度浮點格式數字,並且只能安全地表示-(2^53 - 1)2^53 - 1之間的整數。

所以,現在我們知道了數字“安全”的范圍。 此外,JavaScript ES6 具有內置方法Number.isSafeInteger()來檢查數字是否為安全整數。

從邏輯上講,如果我們想將一個數字n表示為二進制,這個數字需要 53 位的長度,但為了更好地表示,我們使用 7 組 8 位 = 56 位,並根據其符號使用01填充左側padStart函數。

接下來,我們需要處理正數和負數:正數將向左添加0 ,而負數將向左添加1 此外,負數需要二進制補碼表示。 我們可以通過將Number.MAX_SAFE_INTEGER + 1添加到數字來輕松解決此問題。

例如,我們想將-3表示為二進制,假設Number.MAX_SAFE_INTEGER00000000 11111111 (255)那么Number.MAX_SAFE_INTEGER + 1將是00000001 00000000 (256) 現在讓我們添加數字Number.MAX_SAFE_INTEGER + 1 - 3這將是00000000 11111101 (253)但正如我們所說,我們將用1填充左側,例如11111111 11111101 (-3) ,這表示二進制的-3

另一種算法是我們將數字加1並像這樣反轉符號-(-3 + 1) = 2這將是00000000 00000010 (2) 現在我們像這樣反轉每一位11111111 11111101 (-3)再次我們有-3的二進制表示。

在這里,我們有這些算法的工作片段:

 function dec2binA(n) { if (!Number.isSafeInteger(n)) throw new TypeError('n value must be a safe integer') if (n > 2**31) throw 'number too large. number should not be greater than 2**31' if (n < -1*(2**31)) throw 'number too far negative, number should not be lesser than 2**31' const bin = n < 0 ? Number.MAX_SAFE_INTEGER + 1 + n : n const signBit = n < 0 ? '1' : '0' return parseInt(bin, 10).toString(2) .padStart(56, signBit) .replace(/\B(?=(.{8})+(?!.))/g, ' ') } function dec2binB(n) { if (!Number.isSafeInteger(n)) throw new TypeError('n value must be a safe integer') if (n > 2**31) throw 'number too large. number should not be greater than 2**31' if (n < -1*(2**31)) throw 'number too far negative, number should not be lesser than 2**31' const bin = n < 0 ? -(1 + n) : n const signBit = n < 0 ? '1' : '0' return parseInt(bin, 10).toString(2) .replace(/[01]/g, d => +!+d) .padStart(56, signBit) .replace(/\B(?=(.{8})+(?!.))/g, ' ') } const a = -805306368 console.log(a) console.log('dec2binA:', dec2binA(a)) console.log('dec2binB:', dec2binB(a)) const b = -3 console.log(b) console.log('dec2binA:', dec2binA(b)) console.log('dec2binB:', dec2binB(b))

另一種選擇

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));

任何編程語言都可以實現邏輯的實際解決方案:

如果你確定它只是積極的:

var a = 0;
var n = 12; // your input
var m = 1;
while(n) {
    a = a + n%2*m;
    n = Math.floor(n/2);
    m = m*10;
}

console.log(n, ':', a) // 12 : 1100

如果可以消極或積極 -

(n >>> 0).toString(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("---");

這是我使用的一種方法。 這是一種非常快速且簡潔的方法,適用於整數。

如果需要,此方法也適用於 BigInts。 您只需將每個1更改為1n

// Assuming {num} is a whole number
function toBin(num){
    let str = "";
    do {
        str = `${num & 1}${str}`;
        num >>= 1;
    } while(num);
    return str
}

解釋

這種方法在某種程度上遍歷了數字的所有位,就好像它已經是一個二進制數一樣。

它以空字符串開頭,然后添加最后一位。 num & 1將返回數字的最后一位( 10 )。 num >>= 1然后刪除最后一位並使倒數第二位成為新的最后一位。 重復該過程,直到已讀取所有位。

當然,這是對實際情況的極端簡化。 但這就是我概括它的方式。

這是我的代碼:

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();

這就是解決方案。 事實上它很簡單

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.
        */

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM