将二进制补码转换为二进制表示

时间:2019-10-15 14:47:45

标签: javascript floating-point binary numbers twos-complement

我正在执行按位运算,其结果显然存储为二进制补码。当我将鼠标悬停在变量上时,它会存储在-num = -2086528968.

我想要的那个数字的二进制是-(10000011101000100001100000111000)

但是当我说num.toString(2)时,我得到了完全不同的二进制表示形式,即原始数字的二进制而不是2s comp(-1111100010111011110011111001000)。

我如何找回第一个字符串?

链接到转换器:Rapidtables.com/convert/number/decimal-to-binary.html 请输入此号码:-2086528968

2 个答案:

答案 0 :(得分:3)

遵循以下结果:

var number = -2086528968;
    
    var bin = (number >>> 0).toString(2)
    //10000011101000100001100000111000
    console.log(bin)

答案 1 :(得分:2)

pedro已经回答了这个问题,但是由于这是黑客行为,而且不完全直观,因此我将对其进行解释。

  

我正在执行按位运算,其结果显然存储为二进制补码。当我将鼠标悬停在变量上时,会看到num = -2086528968

否,大多数位运算的结果都是32位带符号整数。这意味着0x80000000位将被解释为符号,后跟31位值。

奇怪的位序列是因为JS如何对值进行字符串化,例如sign + Math.abs(value).toString(base);

如何处理?我们需要告诉JS 将该位解释为符号,但作为值的一部分。但是如何?

一个易于理解的解决方案是将0x100000000添加到负数,从而获得正数。

function print(value) {
  if (value < 0) {
    value += 0x100000000;
  }
  console.log(value.toString(2).padStart(32, 0));
}

print(-2086528968);

另一种方法是分别转换低位和高位

function print(value) {
  var signBit = value < 0 ? "1" : "0";
  var valueBits = (value & 0x7FFFFFFF).toString(2);

  console.log(signBit + valueBits.padStart(31, 0));
}

print(-2086528968);


//or lower and upper half of the bits:
function print2(value) {
  var upperHalf = (value >> 16 & 0xFFFF).toString(2);
  var lowerHalf = (value & 0xFFFF).toString(2);
  console.log(upperHalf.padStart(16, 0) + lowerHalf.padStart(16, 0));
}

print2(-2086528968);

另一种方式涉及pedro使用的“ hack”。您还记得我曾说过 most 位操作返回一个int32吗?实际上有一个操作会返回 unsigned (32位)整数,即所谓的Zero-fill right shift

所以number >>> 0不会更改数字的位,但是不再将第一位解释为符号。

function uint32(value){
  return value>>>0;
}

function print(value){
  console.log(uint32(value).toString(2).padStart(32, 0));
}

print(-2086528968);

  

仅当数字为负数或始终为负数时,我才运行此移位代码吗?

通常来说,在正整数上运行nr >>> 0并没有什么害处,但请注意不要过度使用它。

从技术上讲,JS仅支持数字,即double({64bit floating point值)。引擎内部还使用int32值;在可能的情况。但是没有uint32值。因此,当您将否定的int32转换为uint32时,引擎会将其转换为double。而且,如果您再进行一次位操作,那么它要做的第一件事就是将其转换回去。

因此可以在需要实际uint32值的情况下执行此操作,例如在此处打印位,但是最好避免在两次操作之间进行这种转换。就像“只是修复它”。