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

bar*_*lop 266 javascript numbers

我希望看到二进制中的整数,正数或负数.

更喜欢这个问题,但对于JavaScript.

fer*_*vio 446

答案:

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

dec2bin(1);    // 1
dec2bin(-1);   // 11111111111111111111111111111111
dec2bin(256);  // 100000000
dec2bin(-256); // 11111111111111111111111100000000
Run Code Online (Sandbox Code Playgroud)

您可以使用Number.toString(2)函数,但在表示负数时会出现一些问题.例如,(-1).toString(2)输出是"-1".

要解决此问题,可以使用无符号右移位运算符(>>>)将数字强制转换为无符号整数.

如果你运行(-1 >>> 0).toString(2)你将你的数字0位向右移动,这不会改变数字本身,但它将表示为无符号整数.上面的代码将"11111111111111111111111111111111"正确输出.

这个问题有进一步的解释.

-3 >>> 0 (右逻辑移位)将其参数强制转换为无符号整数,这就是为什么得到-3的32位二进制补码表示的原因.


注1:这个答案需要一个Number作为参数,所以相应地转换它.

注意2:结果是没有前导零的字符串,因此请根据需要应用填充.

  • [这里](http://stackoverflow.com/questions/16155592/negative-numbers-to-binary-string)是解释 (6认同)
  • toString(2) 不起作用,因为您从文本获取输入。使用这个: function decToBase(dec, base){ return parseInt(dec).toString(base); } 警报(decToBase(dec, 2)); (2认同)

Man*_*tok 191

尝试

num.toString(2);
Run Code Online (Sandbox Code Playgroud)

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我从这里得到了一些帮助


Ann*_*nan 50

"转换为二进制"中的二进制可以指三个主要内容.位置编号系统,内存中的二进制表示或32位位串.(对于64位位串,请参阅Patrick Roberts的回答)

1.数字系统

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

2.内部代表

数字的内部表示是64位浮点,在这个答案中讨论了一些限制.有没有简单的方法来创建的javascript也不能访问特定位的该位串表示.

3.面具和按位运算符

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

按位运算符将其操作数视为32位序列(零和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"
Run Code Online (Sandbox Code Playgroud)

  • @Magus我想我充分解释了数字和二进制字符串之间的区别.32位二进制字符串总是32个字符长,由"1"和"0"组成.toString返回使用给定基数的位置编号系统表示的*实际*数字.这取决于*为什么*你想要字符串,它们具有非常不同的含义. (5认同)

ad *_*ees 41

一个简单的方法就是......

Number(42).toString(2);

// "101010"
Run Code Online (Sandbox Code Playgroud)

  • 甚至更短的`42..toString(2)` (31认同)
  • 我更喜欢`(42).toString(2)` (23认同)
  • 人们正在努力解决这个问题.答案是正确的,因为它将输入(42)转换为整数并且需要该行.如果从文本输入中获取"数字",则toString(2)将无效. (9认同)
  • @Kapep,Dude那是天才.你怎么知道的? (4认同)
  • @BatuG。数字的语法允许您省略小数点分隔符之后的部分。您可以写与1.0相同的“ 1.”或只是写“ 1”(类似地,您也可以省略前面的部分,而写“ .5”而不是“ 0.5”)。因此,在示例中,第一个点是小数点分隔符,它是数字的一部分,第二个点是用于在该数字上调用方法的点运算符。您必须使用两个点(或将数字括在括号中),并且不能只写`42.toString(2)`,因为解析器将点视为小数点分隔符,并且由于缺少点运算符而引发错误。 (2认同)

Pat*_*rts 28

这个答案试图解决twosComplement(或Number.isSafeInteger())和之间的绝对值的整数Number.isInteger().当前解决方案仅解决32位内的有符号整数,但此解决方案将使用Number.MAX_SAFE_INTEGER以下内容以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));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper{max-height:100%!important}
Run Code Online (Sandbox Code Playgroud)

这个答案主要涉及IEEE-754双精度浮点格式,如下所示:

IEEE-754双精度浮点格式

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));
Run Code Online (Sandbox Code Playgroud)

解决方案的工作方式是在小端字节排序中创建64位浮点数和无符号16位整数数组之间的并集.验证整数输入范围后,它将输入转换为缓冲区上的双精度浮点数,然后使用并集获取对该值的位访问权,并根据无偏二进制指数和分数位计算二进制字符串.

该解决方案在纯ECMAScript 5中实现,除了使用String.prototype.padStart(),这里有一个可用的polyfill.

  • 范围更广?它适用于` - (2**53)-1`到'2**53-1`而不仅仅是` - (2**31)`到`2**31-1`就像annan的答案. (2认同)

bar*_*lop 11

注意 - x.toString(2)当x为正时,基本 有一个小问题.我的答案结尾处有一些示例代码,在使用>>>时使用>>>方法纠正了该问题.

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


createBinaryString(-1)
"11111111 11111111 11111111 11111111"
createBinaryString(1024)
"00000000 00000000 00000100 00000000"
createBinaryString(-2)
"11111111 11111111 11111111 11111110"
createBinaryString(-1024)
"11111111 11111111 11111100 00000000"
Run Code Online (Sandbox Code Playgroud)

一个工作的例子

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


createBinaryString(-1)
"11111111 11111111 11111111 11111111"
createBinaryString(1024)
"00000000 00000000 00000100 00000000"
createBinaryString(-2)
"11111111 11111111 11111111 11111110"
createBinaryString(-1024)
"11111111 11111111 11111100 00000000"
Run Code Online (Sandbox Code Playgroud)

这在URL栏中是另一个快速证明

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


createBinaryString(-1)
"11111111 11111111 11111111 11111111"
createBinaryString(1024)
"00000000 00000000 00000100 00000000"
createBinaryString(-2)
"11111111 11111111 11111111 11111110"
createBinaryString(-1024)
"11111111 11111111 11111100 00000000"
Run Code Online (Sandbox Code Playgroud)

注意 - 结果有轻微缺陷,因为它始终以1开头,对于负数很好.对于正数,你应该在开头前加一个0,这样结果就是2s补码.所以(x>>>0).toString(2);产生1000不是真正的8合2补码,但是前面的0,使其成为01000,是正确的8合2补码.在适当的2s补码中,任何以0开头的位串都是> = 0,任何以1开头的位串都是负的.

例如,这可以解决这个问题

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


createBinaryString(-1)
"11111111 11111111 11111111 11111111"
createBinaryString(1024)
"00000000 00000000 00000100 00000000"
createBinaryString(-2)
"11111111 11111111 11111111 11111110"
createBinaryString(-1024)
"11111111 11111111 11111100 00000000"
Run Code Online (Sandbox Code Playgroud)

其他解决方案来自安南(尽管安南的解释和定义充满了错误,他的代码产生了正确的输出),以及Patrick的解决方案.

任何不理解从0开始的正数和在2s补码中的负数的事实的人都可以在2s补码上检查这个SO QnA.什么是"2的补充"?


sup*_*289 6

您可以编写自己的函数来返回位数组.示例如何将数字转换为位

除数| 股息| 比特/余数

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
}
Run Code Online (Sandbox Code Playgroud)

从下到上阅读余数.数字1在中间到顶部.

  • 原因是 number%2 不等于 number/2。我们对**余数**而不是商感兴趣。 (2认同)

gil*_*niy 5

这是我设法处理它的方式:

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

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


归档时间:

查看次数:

271451 次

最近记录:

5 年,11 月 前