~5 return -6 怎么办?
How does ~5 return -6?
我问这个问题是为了跟进我的 。
W3chools 的页面说:
The examples above uses 4 bits unsigned binary numbers. Because of this ~ 5 returns 10.
Since JavaScript uses 32 bits signed integers, it will not return 10.
It will return -6. 00000000000000000000000000000101 (5)
11111111111111111111111111111010 (~5 = -6)
A signed integer uses the leftmost bit as the minus sign.
反转位并砍掉符号位,数字变为 1111111111111111111111111111010,十进制形式为 2147483642。但是,根据该页面,它的计算结果应为 -6。
我哪里错了?
错误在于32位补码结果的"chopping off the sign bit"。这会将 -6(它的二进制表示中有很多前导 1)转换为 31 位正数,它的二进制表示中仍然有很多前导 1。将-6去掉符号位得到的31位数非常接近32位有符号数的最大正值
不去掉32位整数符号位就可以看到结果:
function unsignedNibble( i) {
return i & 0x0f;
}
function signedNumberBits( n) {
var bits = "";
for( var i = 32; i--;) {
bits = "" + (n&1) + bits;
n = n >> 1;
}
return bits;
}
console.log("Unsigned 4 bit: ");
var un5 = unsignedNibble( 5); // unsigned 4 bits of 5
console.log( "un5 = %s ( 0b%s)", un5, un5.toString(2));
var notUn5 = unsignedNibble( ~un5);
console.log( "~un5 = %s ( 0b%s)", notUn5, notUn5.toString(2));
console.log("Signed 32 bit: ");
var sn5 = 5; // signed number 5
console.log( "sn5 = %s ( 0b%s)", sn5, sn5.toString(2));
var notSn5 = ~sn5;
console.log( "~sn5 = %s ( 0b%s)", notSn5, signedNumberBits(notSn5));
~ operator 只是做位改变。
比如~5=~(00000101)它returns(11111010)=-6
不要让 ~ 运算符太复杂。
@wais
6表示为0000 0110(0已补齐)
现在要得到 -6,我们必须为此生成 2 的补码
步骤 1 -反转所有位(第一个补码)
1111 1001
步骤 2 - 加 1 (0000 0001)
1111 1001 + 0000 0001 = 1111 1010
2的补码,就是把所有的位都补码后在末尾加1,得到负数的绝对值
1111111111111111111111111111010 被称赞得到 ...0101(即 5),但你加 1 得到 6。记住这是你确定的负数,你拍下负号得到 -6 .
JavaScript二进制数以补码格式存储。
这意味着负数是该数加1的按位非。例如:
Binary Representation Decimal value
00000000000000000000000000000101 5
11111111111111111111111111111011 -5
00000000000000000000000000000110 6
11111111111111111111111111111010 -6
00000000000000000000000000101000 40
11111111111111111111111111011000 -40
我问这个问题是为了跟进我的
W3chools 的页面说:
The examples above uses 4 bits unsigned binary numbers. Because of this ~ 5 returns 10.
Since JavaScript uses 32 bits signed integers, it will not return 10.
It will return -6. 00000000000000000000000000000101 (5)
11111111111111111111111111111010 (~5 = -6)
A signed integer uses the leftmost bit as the minus sign.
反转位并砍掉符号位,数字变为 1111111111111111111111111111010,十进制形式为 2147483642。但是,根据该页面,它的计算结果应为 -6。
我哪里错了?
错误在于32位补码结果的"chopping off the sign bit"。这会将 -6(它的二进制表示中有很多前导 1)转换为 31 位正数,它的二进制表示中仍然有很多前导 1。将-6去掉符号位得到的31位数非常接近32位有符号数的最大正值
不去掉32位整数符号位就可以看到结果:
function unsignedNibble( i) {
return i & 0x0f;
}
function signedNumberBits( n) {
var bits = "";
for( var i = 32; i--;) {
bits = "" + (n&1) + bits;
n = n >> 1;
}
return bits;
}
console.log("Unsigned 4 bit: ");
var un5 = unsignedNibble( 5); // unsigned 4 bits of 5
console.log( "un5 = %s ( 0b%s)", un5, un5.toString(2));
var notUn5 = unsignedNibble( ~un5);
console.log( "~un5 = %s ( 0b%s)", notUn5, notUn5.toString(2));
console.log("Signed 32 bit: ");
var sn5 = 5; // signed number 5
console.log( "sn5 = %s ( 0b%s)", sn5, sn5.toString(2));
var notSn5 = ~sn5;
console.log( "~sn5 = %s ( 0b%s)", notSn5, signedNumberBits(notSn5));
~ operator 只是做位改变。
比如~5=~(00000101)它returns(11111010)=-6
不要让 ~ 运算符太复杂。
@wais
6表示为0000 0110(0已补齐)
现在要得到 -6,我们必须为此生成 2 的补码
步骤 1 -反转所有位(第一个补码)
1111 1001
步骤 2 - 加 1 (0000 0001)
1111 1001 + 0000 0001 = 1111 1010
2的补码,就是把所有的位都补码后在末尾加1,得到负数的绝对值
1111111111111111111111111111010 被称赞得到 ...0101(即 5),但你加 1 得到 6。记住这是你确定的负数,你拍下负号得到 -6 .
JavaScript二进制数以补码格式存储。
这意味着负数是该数加1的按位非。例如:
Binary Representation Decimal value
00000000000000000000000000000101 5
11111111111111111111111111111011 -5
00000000000000000000000000000110 6
11111111111111111111111111111010 -6
00000000000000000000000000101000 40
11111111111111111111111111011000 -40