Inverting a binary value of a number

12

我首先想把一个数字转换为二进制,然后按位反转它。 像这样:

数字是793 = 1100011001 然后将二进制值转换为:0011100110

在JavaScript中,我可以执行以下操作:

var x = 793;
document.write(x.toString(2)); // gives 0011100110

这将给出该数字的二进制值。 但是如何进行位反转操作?

我尝试使用~运算符,但它可能无法正常工作。输出结果为:-1100011010


1
我想,使用 793 ^ -1 可以得到任何数字的按位反转值,只需要使用左操作数为 -1 的运算符 ^ 即可。 - Victor
6个回答

12

MooGoo的答案是正确的。

这里有一些关于正在发生的事情的信息... 假设这是一个64位整数。

793 = 1100011001
~793 = -794 = 1111111111111111111111111111111111111111111111111111110011100110
0x3ff = 1111111111
(-793 & 0x3ff) = 11100110

你可以使用以下代码来解决所有情况:

var x = 793; // input value
var y = x.toString(2);
var yl = y.length;
var mask = (Math.pow(2,yl)-1); // calculate mask
var result = ~x & mask;
document.write(result.toString(2)+"<br/>");

1
如果我没记错的话,在JavaScript中,所有东西都是64位的。无论是32位还是64位,结果都将是相同的值。我只是使用了64位,这样我就可以演示负值在二进制中的真实情况。由于“-”在二进制中不存在,但JavaScript试图在数字上显示负号时会很友好。这有意义吗?我不太擅长解释。我发布的解决方案的区别在于它完全是数学的。y和yl部分也可以简化,我只是没有时间去深入研究。 - Mark At Ramp51

11

你需要使用位掩码。

(~793 & 0x3ff).toString(2) //11100110

或者使用异或运算

793 ^ 0x3ff

5
您想要将二进制值与111111111异或 - 数字中有多少个1就有多少个。因此:
var x = 793;
var result = x ^ parseInt((new Array(x.toString(2).length+1)).join("1"),2);

(从PHP.JS中获取的str_repeat代码)

几年后重新审视,尝试:

var x = 793;
var result = parseInt(x.toString(2).replace(/[01]/g,function(n) {return 1-n;}),2);

我相信这样会更有效率...可能吧。完全可能也错了。不过没关系。


如果你要经常使用它,你也可以将其注册为原型函数:Number.prototype.negate = function() {return this ^ parseInt((new Array(this.toString(2).length+1)).join("1"),2);}; - 这样你就可以这样使用:var x = 793; var c = x.negate(); - Niet the Dark Absol
2
天啊,所有这些字符串操作都不太符合位运算的精神,是吗?你也可以像这样做:793..toString(2).replace(/1/g, 'a').replace(/0/g, '1').replace(/a/g, '0'),但你可能会导致某个6502 CPU熔断。 - MooGoo

2

虽然代码不是最短的,但更易读。我的技巧类似于@Ivo Wetzel

const bitwiseComplement = (N) => {
  let binary = N.toString(2); // 793 is "1100011001" in binary
  binary = binary.split('').map(x => {
    return (x == 1) ? 0 : 1;
  }).join('');
  return binary; // with complement "0011100110" in binary
};

console.log(bitwiseComplement(793));

一行JavaScript解决方案。正则表达式/[0-1]/g的意思是匹配下列列表中出现的单个字符[0-1]

const bitwiseComplement = (N) => {
  return N.toString(2).replace(/[0-1]/g, (v) => (v == 1 ? 0 : 1));
};

console.log(bitwiseComplement(793));


0

我只是这样做

假设x = -11.3,它是来自某个地方的16位整数。

我的结果将进入变量r。

var r = ((x & 0x7FFF) ^ 0x7FFF)+1;

这是KISS原则。


1
“-11.3” 怎么是整数? - RalfFriedl
& 0x7FFF 是多余的。 - vanowm

-1

更新

我不确定您是否想要一个反转值的字符串,如果是这样,您可以这样做:

function invert(x){
    var e = x.toString(2).split('');
    for(var i = 0, l = e.length; i < l; i++) {
        e[i] = e[i] === '0' ? '1' : (e[i] === '1' ? '0' : e[i]);
    }
    return e.join('');
}
invert(793); // '0011100110'
invert(-793); // '-0011100110'

这也将保留前导零。


我不明白这如何回答问题,因为与0异或不会改变任何位,就像你展示的那样。 - Greg Hewgill
@Greg 啊,脑子有点迟钝,把错误的东西从我的 shell 复制了过来,我会修复它的。 - Ivo Wetzel
将一个元素与 0 进行异或操作不会产生任何影响。 - 6502
抱歉,睡眠不足 :/ 已更新答案。 - Ivo Wetzel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接