在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:36:26  来源:igfitidea点击:

1's complement using ~ in C/C++

c++cunsignedsignedones-complement

提问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 -11in 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 coutdisplay 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 10is 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..000then +1: 000..001. Result: -1.

将如何cout显示结果?它查看原始类型。对于有符号整数,最高有效位是其符号。因此,结果始终为(因为 中的最高有效位100)。要将负数显示为正数,您需要补码:将所有位取反,然后加 1。例如,-1, binary 111..111,显示为 (inverting) 000..000then +1: 000..001。结果:-1

Applying this to the one's complement of 10you get 111..110101-> inverting to 000...001010, then add 1. Result: -11.

将此应用到10您的补码中得到111..110101-> 反转为000...001010,然后添加1. 结果:-11。

For an unsignednumber, coutdoesn'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;
}