Johnny Pauling
Johnny Pauling

Reputation: 13417

unsigned-signed underflow mechanism

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

Answers (4)

jthill
jthill

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

James Kanze
James Kanze

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

Mats Petersson
Mats Petersson

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

Saqlain
Saqlain

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

Related Questions