Assigning negative numbers to an unsigned int?

C

C Problem Overview


In the C programming language, unsigned int is used to store positive values only. However, when I run the following code:

unsigned int x = -12;
printf("%d", x);

The output is still -12. I thought it should have printed out: 12, or am I misunderstanding something?

C Solutions


Solution 1 - C

The -12 to the right of your equals sign is set up as a signed integer (probably 32 bits in size) and will have the hexadecimal value 0xFFFFFFF4. The compiler generates code to move this signed integer into your unsigned integer x which is also a 32 bit entity. The compiler assumes you only have a positive value to the right of the equals sign so it simply moves all 32 bits into x. x now has the value 0xFFFFFFF4 which is 4294967284 if interpreted as a positive number. But the printf format of %d says the 32 bits are to be interpreted as a signed integer so you get -12. If you had used %u it would have printed as 4294967284.

In either case you don't get what you expected since C language "trusts" the writer of code to only ask for "sensible" things. This is common in C. If you wanted to assign a value to x and were not sure whether the value on the right side of the equals was positive you could have written unsigned int x = abs(-12); and forced the compiler to generate code to take the absolute value of a signed integer before moving it to the unsigned integer.

Solution 2 - C

The int is unsinged, but you've told printf to look at it as a signed int.

Try

unsigned int x = -12; printf("%u", x);

It won't print "12", but will print the max value of an unsigned int minus 11.

Exercise to the reader is to find out why :)

Solution 3 - C

Passing %d to printf tells printf to treat the argument as a signed integer, regardless of what you actually pass. Use %u to print as unsigned.

Solution 4 - C

It all has to do with interpretation of the value.

If you assume 16 bit signed and unsigned integers, then here some examples that aren't exactly correct, but demonstrate the concept.

0000 0000 0000 1100 unsigned int, and signed int value 12

1000 0000 0000 1100 signed int value -12, and a large unsigned integer.

For signed integers, the bit on the left is the sign bit. 0 = positive 1 = negative

For unsigned integers, there is no sign bit. the left hand bit, lets you store a larger number instead.

So the reason you are not seeing what you are expecting is that.

unsigned int x = -12, takes -12 as an integer, and stores it into x. x is unsigned, so what was a sign bit, is now a piece of the value.

printf lets you tell the compiler how you want a value to be displayed.

%d means display it as if it were a signed int. %u means display it as if it were an unsigned int.

c lets you do this kind of stuff. You the programmer are in control.

Kind of like a firearm. It's a tool. You can use it correctly to deal with certain situations, or incorrectly to remove one of your toes.

one possibly useful case is the following

unsigned int allBitsOn = -1;

That particular value sets all of the bits to 1

1111 1111 1111 1111

that can be useful sometimes.

Solution 5 - C

printf('%d', x); 

Means print a signed integer. You'll have to write this instead:

printf('%u', x);

Also, it'll still not print "12", it's going to be "4294967284".

Solution 6 - C

They do store positive values. But you're outputting the (very high) positive value as a signed integer, so it gets re-interpreted again (in an implementation-defined fashion, I might add).

Use the format flag "%u instead.

Solution 7 - C

Your program has undefined behavior because you passed the wrong type to printf (you told it you were going to pass an int but you passed an unsigned int). Consider yourself lucky that the "easiest" thing for the implementation to do was just silently print the wrong value and not jump to some code that does something harmful...

Solution 8 - C

What you are missing is that the printf("%d",x) expects x to be signed, so although you assign -12 to x it is interpreted as 2's complement which would be a very large number. However when you pass this really large number to printf it interprets it as signed thus correctly translating it back to -12.

The correct syntax to print a unsigned in print f is "%u" - try this and see what it does!

Solution 9 - C

The assignment of a negative value to an unsigned int does not compute the absolute value of the negative: it interprets as an unsigned int the binary representation of the negative value, i.e., 4294967284 (2^32 - 12).

printf("%d") performs the opposite interpretation. This is why your program displays -12.

Solution 10 - C

int and unsigned int are used to allocate a number of bytes to store a value nothing more.

The compiler should give warnings about signed mismatching but it really does not affect the bits in the memory that represent the value -12.

%x, %d, %u etc tells the compiler how to interrupt a number of bits when you print them.

Solution 11 - C

When you are trying to display the int value you are passing it to a (int) argument and not a (unsigned int) argument and that causes it to print -12 and not 4294967284. Integers are stored in hexadecimal format and -12 for int is the same as 4294967284 for unsigned int in hexadecimal format.. That is why "%u" prints the right value you want and not "%d".. It depends on your argument type..GOOD LUCK!

Solution 12 - C

The -12 is in 16-bit 2's compliment format. So do this: if (x & 0x8000) { x = ~x+1; } This will convert the 2's compliment -ve number to the equivalent +ve number. Good luck.

Solution 13 - C

When the compiler implicitly converts -12 to an unsigned integer, the underlying binary representation remains unaltered. This conversion is purely semantic. The sign bit of the two's complement integer becomes the most significant bit of the unsigned integer. Thus when printf treats the unsigned integer as a signed integer with %d, it will see -12.

Solution 14 - C

In general context when only positive numbers can be stored, negative numbers are not stored explicitly but their 2's complement is stored. In the same way here, the 2's complement of -12 will be stored in 'x' and you use %u to get it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionipkissView Question on Stackoverflow
Solution 1 - CTim OltroggeView Answer on Stackoverflow
Solution 2 - CBinary WorrierView Answer on Stackoverflow
Solution 3 - CErikView Answer on Stackoverflow
Solution 4 - CEvilTeachView Answer on Stackoverflow
Solution 5 - CLinus KleenView Answer on Stackoverflow
Solution 6 - CLightness Races in OrbitView Answer on Stackoverflow
Solution 7 - CR.. GitHub STOP HELPING ICEView Answer on Stackoverflow
Solution 8 - CElementalView Answer on Stackoverflow
Solution 9 - CmouvicielView Answer on Stackoverflow
Solution 10 - CtrevorView Answer on Stackoverflow
Solution 11 - CVern01View Answer on Stackoverflow
Solution 12 - CNichola TeslaView Answer on Stackoverflow
Solution 13 - CEMRView Answer on Stackoverflow
Solution 14 - CKingView Answer on Stackoverflow