在 C/C++ 中使用 ~ 的 1 的补码
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23978683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
1's complement using ~ in C/C++
提问by user2912611
I am using Visual Studio 2013.
Recently I tried the ~
operator for 1's complement:
我正在使用 Visual Studio 2013。
最近我尝试了~
1 的补码运算符:
int a = 10;
cout << ~a << endl;
Output is -11
输出是 -11
But for
但对于
unsigned int a = 10;
cout << ~a << endl;
the output is 4294967296
输出是 4294967296
I don't get why the output is -11
in the case of signed int
.
Please help me with this confusion.
我不明白为什么输出是-11
在 signed 的情况下int
。请帮我解决这个困惑。
回答by Ivan Kuckir
When you put number 10 into 32-bit signed or unsigned integer, you get
当您将数字 10 放入 32 位有符号或无符号整数时,您会得到
0000 0000 0000 0000 0000 0000 0000 1010
When you negate it, you get
当你否定它时,你得到
1111 1111 1111 1111 1111 1111 1111 0101
These 32 bits mean 4294967285 as an unsigned integer, or -11 as a signed integer (your computer represents negative integers as Two's complement). They can also mean a 32-bit floating point number or four 8-bit characters.
这 32 位表示 4294967285 作为无符号整数,或 -11 作为有符号整数(您的计算机将负整数表示为二进制补码)。它们也可以表示一个 32 位浮点数或四个 8 位字符。
Bits don't have any "absolute" meaning. They can represent anything, depending on how you "look" at them (which type they have).
位没有任何“绝对”含义。它们可以代表任何东西,这取决于您如何“看待”它们(它们具有哪种类型)。
回答by usr2564301
The ~
operator performs a ones-complementon its argument, and it does not matter whther the argument is a signed or unsigned integer. It merely flips all the bits, so
该~
运算符执行者补上它的参数,并不要紧whther参数是一个符号或无符号整数。它只是翻转所有的位,所以
0000 0000 0000 1010 (bin) / 10 (dec)
becomes
变成
1111 1111 1111 0101 (bin)
(where, presumably, these numbers are 32 bits wide -- I omitted 16 more 0's and 1's.)
(据推测,这些数字是 32 位宽——我又省略了 16 个 0 和 1。)
How will cout
display the result? It looks at the original type. For a signedinteger, the most significant bit is its sign. Thus, the result is always going to be negative(because the most significant bit in 10
is 0
). To display a negative number as a positive one, you need the two's complement: inverting all bits, then add 1. For example, -1
, binary 111..111
, displays as (inverting) 000..000
then +1: 000..001
. Result: -1
.
将如何cout
显示结果?它查看原始类型。对于有符号整数,最高有效位是其符号。因此,结果始终为负(因为 中的最高有效位10
是0
)。要将负数显示为正数,您需要补码:将所有位取反,然后加 1。例如,-1
, binary 111..111
,显示为 (inverting) 000..000
then +1: 000..001
。结果:-1
。
Applying this to the one's complement of 10
you get 111..110101
-> inverting to 000...001010
, then add 1
. Result: -11.
将此应用到10
您的补码中得到111..110101
-> 反转为000...001010
,然后添加1
. 结果:-11。
For an unsignednumber, cout
doesn't do this (naturally), and so you get a large number: the largest possible integer minusthe original number.
对于无符号数,cout
不这样做(自然),因此您会得到一个大数:最大可能的整数减去原始数。
回答by usr2564301
In memory there is stored 4294967285 in both cases (4294967296 properly a typo, 33 bit?), the meaning of this number depends which signdeness you use:
在两种情况下,内存中都存储了 4294967285(4294967296 正确地是一个错字,33 位?),这个数字的含义取决于您使用的符号:
- if it's signed, this the number is -11.
- if it's unsigned, then it's 4294967285
- 如果已签名,则此数字为 -11。
- 如果未签名,则为 4294967285
different interpretations of the same number.
同一个数字的不同解释。
You can reinterpret it as unsigned by casting it, same result:
您可以通过强制转换将其重新解释为无符号,结果相同:
int a = 10;
cout << (unsigned int) ~a << endl;
回答by Agnit
Try this
尝试这个
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;
}