我正在使用 Visual Studio 2013。
最近我尝试了~
1 的补码运算符:
int a = 10;
cout << ~a << endl;
输出是-11
但对于
unsigned int a = 10;
cout << ~a << endl;
输出是4294967296
我不明白为什么输出是-11
有符号的int
。请帮我解决这个困惑。
我正在使用 Visual Studio 2013。
最近我尝试了~
1 的补码运算符:
int a = 10;
cout << ~a << endl;
输出是-11
但对于
unsigned int a = 10;
cout << ~a << endl;
输出是4294967296
我不明白为什么输出是-11
有符号的int
。请帮我解决这个困惑。
当您将数字 10 放入 32 位有符号或无符号整数时,您会得到
0000 0000 0000 0000 0000 0000 0000 1010
当你否定它时,你得到
1111 1111 1111 1111 1111 1111 1111 0101
这 32 位表示 4294967285 作为无符号整数,或 -11 作为有符号整数(您的计算机将负整数表示为二进制补码)。它们也可以表示一个 32 位浮点数或四个 8 位字符。
位没有任何“绝对”含义。它们可以代表任何东西,这取决于您如何“看待”它们(它们具有哪种类型)。
运算符对其参数~
执行补码,参数是有符号整数还是无符号整数都没有关系。它只是翻转所有位,所以
0000 0000 0000 1010 (bin) / 10 (dec)
变成
1111 1111 1111 0101 (bin)
(据推测,这些数字是 32 位宽——我又省略了 16 个 0 和 1。)
将如何cout
显示结果?它着眼于原始类型。对于有符号整数,最高有效位是它的符号。因此,结果总是负数(因为最重要的位10
是0
)。要将负数显示为正数,您需要二进制补码:反转所有位,然后加 1。例如,-1
, binary 111..111
,显示为 (inverting)000..000
然后 +1: 000..001
。结果:-1
。
将此应用于10
您的补码111..110101
-> 反转为000...001010
,然后添加1
。结果:-11。
对于无符号数,cout
(自然)不会这样做,因此您会得到一个大数:可能的最大整数减去原始数。
在内存中,两种情况下都存储了 4294967285(4294967296 是错字,33 位?),这个数字的含义取决于您使用的符号:
同一个数字的不同解释。
您可以通过强制转换将其重新解释为无符号,结果相同:
int a = 10;
cout << (unsigned int) ~a << endl;
尝试这个
unsigned int getOnesComplement(unsigned int number){
unsigned onesComplement = 1;
if(number < 1)
return onesComplement;
size_t size = (sizeof(unsigned int) * 8 - 1) ;
unsigned int oneShiftedToMSB = 1 << size;
unsigned int shiftedNumber = number;
for ( size_t bitsToBeShifted = 0; bitsToBeShifted < size; bitsToBeShifted++){
shiftedNumber = number << bitsToBeShifted;
if(shiftedNumber & oneShiftedToMSB){
onesComplement = ~shiftedNumber;
onesComplement = onesComplement >> bitsToBeShifted;
break;
}
}
return onesComplement;
}