如何在JavaScript中将整数转换为二进制?

我希望看到二进制形式的正整数或负整数。

很像这个问题,但是是JavaScript。

553113 次浏览

试一试

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

我从在这里得到了一些帮助

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(右逻辑移位)将其参数强制为无符号整数,这就是为什么你得到32位2的-3补表示。

一个简单的方法就是……

Number(42).toString(2);


// "101010"

“convert to binary”中的二进制可以指三个主要的东西。位置数系统,内存中的二进制表示或32位位串。(64位位串参见帕特里克·罗伯茨的回答)

1. 数字系统

(123456).toString(2)将数字转换为以2为基数的位置数制。在这个系统中,负数被写成负号,就像在十进制中一样。

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"

对于32位来说,我想要的解决方案是这个答案末尾的代码,它来自developer.mozilla.org(MDN),但是添加了一些行,用于A)格式化和B)检查数字是否在范围内。

一些人建议x.toString(2),它对负号不起作用,它只是在那里为它们粘贴了一个负号,这是不好的。

Fernando提到了(x>>>0).toString(2);的一个简单的解决方案,它适用于负数,但当x为正数时有一个小问题。它的输出从1开始,对于正数来说不是2s的补码。

任何不理解正数以0开始和负数以1开始的事实的人,在2s补中,可以在2s补中检查这个SO QnA。什么是“2's Complement”?

一个解决方案可能包括在正数前面加上一个0,这是我在这个答案的早期修订中所做的。人们有时可以接受一个33位的数字,或者可以确保要转换的数字在-(2^31)<=x<2^31-1的范围内。所以这个数字总是32位的。但是,您可以在mozilla.org上使用这个解决方案

Patrick的答案和代码很长,显然适用于64位,但有一个bug,一个评论者发现了,并且评论者修复了Patrick的bug,但Patrick有一些“神奇的数字”。在他的代码中,他没有评论,也已经忘记了,帕特里克不再完全理解他自己的代码/为什么它可以工作。

安南有一些不正确和不清楚的术语,但提到了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位为一组格式化输出。基于如何用逗号作为千位分隔符格式化一个数字?(我只是修改了它,从在3 s中从右向左分组并添加逗号,到在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 |

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从中间到上面。

这个答案试图用214748364810 (231) - 900719925474099110 (253-1)范围内的绝对值来处理输入。


在JavaScript中,数字存储在64位浮点表示法中,但位操作将它们强制转换为32位整数存储在二补格式中,因此任何使用位操作的方法都将输出范围限制为- 2147483648__abc3 (- 2__abc4) - 214748364710 (231-1)。

然而,如果避免按位操作,并且仅使用数学运算来保留64位浮点表示法,则可以通过对53位的twosComplement进行符号扩展,可靠地将任何安全的整数转换为64位的2补二进制表示法:

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}

For older browsers, polyfills exist for the following functions and values:

As an added bonus, you can support any radix (2–36) if you perform the two's complement conversion for negative numbers in ⌈64 / log2(radix)⌉ digits by using 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}

If you are interested in my old answer that used an ArrayBuffer to create a union between a Float64Array and a Uint16Array, please refer to this answer's revision history.

这是我的代码:

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

我用了一种不同的方法来解决这个问题。我决定在我的项目中不使用这段代码,但我想我会把它放在相关的地方,以防它对某人有用。

  • 不使用位移位或双补强制。
  • 你选择输出的比特数(它检查有效值'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("---");

还有一个选择

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

我是这样处理的:

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

这是我常用的方法。这是一个非常快速和简洁的方法,适用于整数。

如果你愿意,这个方法也适用于bigint。你只需要将每个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 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)

我希望看到二进制形式的正整数或负整数。

这是一个老问题,我认为这里有很好的解决方案,但没有解释这些聪明的解决方案的使用。

首先,我们需要理解一个数字可以是正数也可以是负数。 此外,JavaScript提供了一个MAX_SAFE_INTEGER常量,其值为9007199254740991。这个数字背后的原因是JavaScript使用IEEE 754中指定的双精度浮点格式数字,并且只能安全地表示-(2^53 - 1)2^53 - 1之间的整数

所以,现在我们知道了数字“安全”的范围。此外,JavaScript ES6有内置方法Number.isSafeInteger()来检查一个数字是否是安全的整数。

逻辑上,如果我们想用二进制表示一个数字n,这个数字需要53位的长度,但为了更好的表示,我们使用7组8位= 56位,并使用padStart函数根据其符号将左侧填充为01

接下来,我们需要处理正数和负数:正数将在左边添加__abc0,而负数将在左边添加__abc1。同样,负数将需要一个二补表示。我们可以通过在数字上添加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),但正如我们所说,我们将用Number.MAX_SAFE_INTEGER0填充左侧,如Number.MAX_SAFE_INTEGER1 Number.MAX_SAFE_INTEGER2,这表示二进制的-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))