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

很像这个问题,但是是针对JavaScript的。


当前回答

对于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的补”?

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

Patrick的回答和代码很长,显然适用于64位,但有一个bug,评论者发现了,评论者修复了Patrick的bug,但Patrick在他的代码中有一些“神奇的数字”,他没有评论,已经忘记了,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秒分组,加逗号,到右到左按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"

其他回答

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

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

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

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

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

接下来,我们需要处理正数和负数:正数左边加0,负数左边加1。同样,负数将需要一个二补表示。我们可以很容易地通过添加Number来解决这个问题。MAX_SAFE_INTEGER + 1的数字。

例如,我们想将-3表示为二进制,让我们假设Number。MAX_SAFE_INTEGER = 00000000 11111111 (255) then 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))

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

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"

还有一个选择

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

对于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的补”?

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

Patrick的回答和代码很长,显然适用于64位,但有一个bug,评论者发现了,评论者修复了Patrick的bug,但Patrick在他的代码中有一些“神奇的数字”,他没有评论,已经忘记了,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秒分组,加逗号,到右到左按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"

我是这样处理的:

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

从这个链接获得:https://locutus.io/php/math/decbin/