Reputation: 5179
Coming from a typeless language (PHP) I'm a bit confused about datatypes in C. I'm facing the following strange behavior.
//First case
unsigned int a;
a = -1;
printf("a = %u", a); //Outputs a strange number, no problem here
//Second case
unsigned int a;
a = -1;
printf("a = %d", a); //Outputs -1
What I don't understand is how a
"contained" a signed value after we specifically said it's unsigned
?
How can only formatting the output in the second case do that?
Upvotes: 1
Views: 4896
Reputation: 1616
As other already said you must always keep in mind the difference between a value and its representation, since in C these two concepts are widely separated.
With assignment you put a value into a specific area of memory; with printf() and similar you try to interpret such value.
For clarification try to understand this:
#include <stdio.h>
int main() {
int val = 2181448;;
printf("%s\n", ((char*)&val)); // * Outputs: "HI!"
return 0;
}
This will print "HI!" because with the assignment you put in a contiguous area of memory ('int' is at least 4 bytes wide here) the number "2181448", which in hexadecimal is 0x00214948, that is:
If you make printf interpret it as a string (note that the cast is only to avoid compiler warnings) (*due to reverse endianess) you see outputted such number as a 4-length string zero-terminated 'H' 'I' '!' '\0'
Upvotes: 4
Reputation: 215235
The compiler will translate -1 to the correct signed number format for your system, in 99.9% of all cases this will be two's complement. On a two's complement system with 32 bit ints, -1 will correspond to 0xFFFFFFFF. But if you store that in an unsigned variable, you will get the value 4.29 billion.
You then attempt to print 4.29 billion using the %d format specifier, which is reserved for negative numbers. The program then interprets 0xFFFFFFFF as -1 again.
To sum it up, there is no such thing as negative numbers on a binary level. Depending on how you chose to display the binary, you can form negative numbers. Still, it is all just ones and zeroes: you cannot save a minus sign in a computer memory cell.
Upvotes: 2
Reputation: 33573
Because that is what printf
does. It doesn't know the type of the supplied values. So it will take the data it finds in a
and interpret it as a signed integer, because you tell it to do so by giving it %d
.
printf
can also be quite dangerous if you put in the incorrect values for formatting codes, or completely omit them. Your program will crash without any message.
Upvotes: 3
Reputation: 29986
The -1
will be represented as something like 10000000 00000000 00000000 00000001
(if int
has 4 bytes as in my case). When you are outputting it with %d
, the printf()
interprets it as a normal int, thus it interprets the leading 1
as the sign, and prints -1
. If you output it as %u
, printf()
knows it's unsigned, and interprets the leading 1
as 2^32
, resulting in 4294967295
as output.
Upvotes: 3