var reverseBits = function(n) {
var re = 0;
for( var i = 0; i < 32; i++ ) {
re = (re << 1) | (n & 1);
n >>>= 1;
}
return re;
};
这是我在Javascript中反转位的代码,但是当n = 1时,它给出-2147483648(-10000000000000000000000000000000),它不应该是正数吗?我哪里错了?
答案 0 :(得分:2)
您获得负数的原因是计算机存储负数和正数。最高有效位(具有最大值的位)用于符号编号,以确定数字是负数还是正数。如果此位是0
,那么它是正数。如果它是1
,那么它是否定的。计算机使用名为2's compliment的技术将数字从负数转换为正数。以下是它的工作原理:
在您的示例中,您将号码1
分配给n
。在32位计算机中,二进制文件看起来像这样:
0000 0000 0000 0000 0000 0000 0000 0001
反转你的位后,你的二进制文件如下所示:
1000 0000 0000 0000 0000 0000 0000 0000
如果您拿出二进制计算器并输入此数字并将其转换为十进制数,则会看到其值2147483648
。因为最左边的位是1
,所以它是负数。由于Javascript只有通用var
变量,因此它假定您需要签名结果。 JavaScript中的>>>
运算符称为zero-fill right shift
,并使用操作数0
(>>> 0
),告诉Javascript您想要无符号结果。
如果你好奇(或者这篇文章的其他读者很好奇),这里是基于二进制的计算机如何处理负数。假设您要存储值-96
。计算机如何存储?首先,忽略这个标志。二进制文件中的96
如下所示:
0000 0000 0000 0000 0000 0000 0110 0000
接下来,计算机会执行2次恭维。这是通过首先反转每个位(1&#39; s变为0&0;以及0&#39; s变为1&#39; s)来实现的:
1111 1111 1111 1111 1111 1111 1001 1111
最后,您只需添加1,如下所示:
1111 1111 1111 1111 1111 1111 1010 0000
在内部,这就是它存储在您计算机内存中的方式。这相当于4,294,967,200
或-96
答案 1 :(得分:1)
不应该是正数吗?我哪里错了?
不,不应该。除>>>
之外的所有按位运算符都使用带符号的 32位整数,其中前导1(以二进制补码表示)表示负数。
正如@Icemanind所建议的那样,您可以使用>>>
的无符号来修复它并将其“转换”为无符号整数:
return re >>> 0;