C: unary minus operator behavior with unsigned operands

落花浮王杯 提交于 2020-01-18 04:29:44

问题


I can't seem to find the relevant parts in the C standard fully defining the behavior of the unary minus operator with unsigned operands.

The 2003 C++ standard (yes, C++, bear with me for a few lines) says in 5.3.1c7: The negative of an unsigned quantity is computed by subtracting its value from 2^n, where n is the number of bits in the promoted operand.

The 1999 C standard, however, doesn't include such an explicit statement and does not clearly define the unary - behavior neither in 6.5.3.3c1,3 nor in 6.5c4. In the latter it says Some operators (the unary operator ~, and the binary operators <<, >>, &, ^, and |, ...) ... return values that depend on the internal representations of integers, and have implementation-defined and undefined aspects for signed types.), which excludes the unary minus and things seem to remain vague.

This earlier question refers to the K&R ANSI C book, section A.7.4.5 that says The negative of an unsigned quantity is computed by subtracting the promoted value from the largest value of the promoted type and adding one.

What would be the 1999 C standard equivalent to the above quote from the book?

6.2.5c9 says: A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.

Is that it? Or is there something else I'm missing?


回答1:


Yes, 6.2.5c9 is exactly the paragraph that you looked for.




回答2:


The behavior of the unary minus operator on unsigned operands has nothing to do with whether a machine uses two's-complement arithmetic with signed numbers. Instead, given unsigned int x,y; the statement y=-x; will cause y to receive whatever value it would have to hold to make x+y equal zero. If x is zero, y will likewise be zero. For any other value of x, it will be UINT_MAX-x+1, in which case the arithmetic value of x+y will be UINT_MAX+1+(y-y) which, when assigned to a unsigned integer, will have UINT_MAX+1 subtracted from it, yielding zero.




回答3:


In every implementation I know of, a negative is calculated as two's complement...

int a = 12;
int b = -a;
int c = ~a + 1;
assert(b == c);

...so there is really no physical difference between negative signed and "negative" unsigned integers - the only difference is in how they are interpreted.

So in this example...

unsigned a = 12;
unsigned b = -a;
int c = -a;

...the b and c are going to contain the exact same bits. The only difference is that b is interpreted as 2^32-12 (or 2^64-12), while c is interpreted as "normal" -12.

So, a negative is calculated in the exact same way regardless of "sign-ness", and the casting between unsigned and signed is actually a no-op (and can never cause an overflow in a sense that some bits need to be "cut-off").



来源:https://stackoverflow.com/questions/8026694/c-unary-minus-operator-behavior-with-unsigned-operands

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!