Reputation: 13417
I know that the following
unsigned short b=-5u;
evaluates to b being 65531 due to an underflow, but I don't understand if 5u is converted to a signed int before being transformed into -5 and then re-converted back to unsigned to be stored in b or -5u is equal to 0 - 5u (this should not be the case, -x is a unary operator)
Upvotes: 4
Views: 1539
Reputation: 60305
5u
is a literal unsigned integer, -5u
is its negation.. Negation for unsigned integers is defined as subtraction from 2**n, which gets the same result as wrapping the result of subtraction from zero.
Upvotes: 5
Reputation: 153929
5u
is a single token, an rvalue expression which has type unsigned int
.
The unary -
operator is applied to it according to the rules of unsigned
arithmetic (arithmetic modulo 2^n, where n is the number of bits in the
unsigned type). The results are converted to unsigned short
; if they don't
fit (and they won't if sizeof(int) > sizeof(short)
), the conversion will
be done using modulo arithmetic as well (modulo 2^n, where n is the number of
bits in the target type).
It's probably worth noting that if the original argument has type unsigned
short
, the actual steps are different (although the results will always be
the same). Thus, if you'd have written:
unsigned short k = 5;
unsigned short b = -k;
the first operation would depend on the size of short. If shorts are smaller
than ints (often, but not always the case), the first step would be to promote
k
to an int
. (If the size of short and int are identical, then the first
step would be to promote k
to unsigned int
; from then on, everything
happens as above.) The unary -
would be applied to this int
, according to
the rules of signed integer arithmetic (thus, resulting in a value of -5). The
resulting -5 will be implicitly converted to unsigned short
, using modulo
arithmetic, as above.
In general, these distinctions don't make a difference, but in cases where you
might have an integral value of INT_MIN
, they could; on 2's complement
machines, -i
, where i
has type int
and value INT_MIN
is implementation
defined, and may result in strange values when later converted to unsigned.
Upvotes: 3
Reputation: 129374
Technically not an underflow, just the representation of the signed value -5
when shown as an unsigned number. Note that signed and unsigned numbers have the same "bits" - they just display differently. If you were to print the value as a signed value [assuming it's extended using the sign bit to fill the remaining bits], it would show -5. [This assumes that it's a typical machine using 2s complement. The C standard doesn't require that signed
and unsigned
types are the same number of bits, nor that the computer uses 2s complement for representing signed numbers - obviously, if it's not using 2s complement, it won't match up to the value you've shown, so I made the assumption that yours IS a 2s complement machine - which is all common processors, such as x86, 68K, 6502, Z80, PDP-11, VAX, 29K, 8051, ARM, MIPS. But technically, it is not necessary for C to function correctly]
And when you use the unary operator -x
, it has the same effect as 0-x
[this applies for computers as well as math - it has the same result].
Upvotes: 0
Reputation: 17928
ISO/IEC 14882-2003 section 4.7 says:
"If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2^n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). —end note ]
Upvotes: 1