ckv
ckv

Reputation: 10820

What happens if I assign a negative value to an unsigned variable?

I was curious to know what would happen if I assign a negative value to an unsigned variable.

The code will look somewhat like this.

unsigned int nVal = 0;
nVal = -5;

It didn't give me any compiler error. When I ran the program the nVal was assigned a strange value! Could it be that some 2's complement value gets assigned to nVal?

Upvotes: 98

Views: 120722

Answers (6)

Dennis Zickefoose
Dennis Zickefoose

Reputation: 10969

For the official answer - Section 4.7 conv.integral for conversion from signed integral types.

"If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n 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 ]

This essentially means that if the underlying architecture stores in a method that is not Two's Complement (like Signed Magnitude, or One's Complement), that the conversion to unsigned must behave as if it was Two's Complement.

(C++20 and later require that signed integers use 2's complement, but earlier versions of the standard allowed those other representations.)

The "... congruent ..." part means that you add or subtract 2n until the value is in the value-range of the unsigned type. For 2's complement, this means doing 2's complement sign-extension or truncation. For the same width, the bit-pattern is unchanged because adding 2n is a no-op: the low n bits of 2n are all zero. 2's complement addition/subtraction are the same bitwise operation as unsigned, which is what makes it special.


PS. conversion from floating point to unsigned works differently: it's undefined behavior if the value is out of range for the unsigned type (if it's negative after truncation to integer or too large). Modulo reduction only happens for signed integer to unsigned integer.

Upvotes: 84

Zafeer
Zafeer

Reputation: 89

When you assign a negative value to an unsigned variable then it uses the 2's complement method to process it and in this method it flips all 0s to 1s and all 1s to 0s and then adds 1 to it. In your case, you are dealing with int which is of 4 byte(32 bits) so it tries to use 2's complement method on 32 bit number which causes the higher bit to flip. For example:

┌─[student@pc]─[~]
└──╼ $pcalc 0y00000000000000000000000000000101      # 5 in binary
        5                       0x5                     0y101
┌─[student@pc]─[~]
└──╼ $pcalc 0y11111111111111111111111111111010      # flip all bits  
      4294967290      0xfffffffa      0y11111111111111111111111111111010
┌─[student@pc]─[~]
└──╼ $pcalc 0y11111111111111111111111111111010 + 1  # add 1 to that flipped binarry
      4294967291      0xfffffffb      0y11111111111111111111111111111011

Upvotes: 3

Martin
Martin

Reputation: 2971

Yes, you're correct. The actual value assigned is something like all bits set except the third. -1 is all bits set (hex: 0xFFFFFFFF), -2 is all bits except the first and so on. What you would see is probably the hex value 0xFFFFFFFB which in decimal corresponds to 4294967291.

Upvotes: 2

Jasmeet
Jasmeet

Reputation: 2352

It will assign the bit pattern representing -5 (in 2's complement) to the unsigned int. Which will be a large unsigned value. For 32 bit ints this will be 2^32 - 5 or 4294967291

Upvotes: 45

perimosocordiae
perimosocordiae

Reputation: 17787

You're right, the signed integer is stored in 2's complement form, and the unsigned integer is stored in the unsigned binary representation. C (and C++) doesn't distinguish between the two, so the value you end up with is simply the unsigned binary value of the 2's complement binary representation.

Upvotes: 5

Dror Helper
Dror Helper

Reputation: 30780

It will show as a positive integer of value of max unsigned integer - 4 (value depends on computer architecture and compiler).

BTW
You can check this by writing a simple C++ "hello world" type program and see for yourself

Upvotes: 4

Related Questions