Reputation: 1646
I have the following code:
#include <stdio.h>
int main() {
unsigned int a = -1;
int b = -1;
printf("%x\n", a);
printf("%x\n", b);
printf("%d\n", a);
printf("%d\n", b);
printf("%u\n", a);
printf("%u\n", b);
return 0;
}
The output is:
ffffffff
ffffffff
-1
-1
4294967295
4294967295
I can see that a value is interpreted as signed or unsigned according to the value passed to printf
function. In both cases, the bytes are the same (ffffffff
). Then, what is the unsigned
word for?
Upvotes: 32
Views: 263039
Reputation: 154312
Assign a int -1
to an unsigned
: As -1
does not fit in the range [0...UINT_MAX]
, multiples of UINT_MAX+1
are added until the answer is in range. Evidently UINT_MAX
is pow(2,32)-1 or 429496725
on OP's machine so a
has the value of 4294967295.
unsigned int a = -1;
The "%x"
, "%u"
specifier expects a matching unsigned
. Since these do not match, "If a conversion specification is invalid, the behavior is undefined.
If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined." C11 §7.21.6.1 9. The printf specifier does not change b
.
printf("%x\n", b); // UB
printf("%u\n", b); // UB
The "%d"
specifier expects a matching int
. Since these do not match, more UB.
printf("%d\n", a); // UB
Given undefined behavior, the conclusions are not supported.
both cases, the bytes are the same (ffffffff).
Even with the same bit pattern, different types may have different values. ffffffff
as an unsigned
has the value of 4294967295. As an int
, depending signed integer encoding, it has the value of -1, -2147483647 or TBD. As a float
it may be a NAN.
what is unsigned word for?
unsigned
stores a whole number in the range [0 ... UINT_MAX]
. It never has a negative value. If code needs a non-negative number, use unsigned
. If code needs a counting number that may be +, - or 0, use int
.
Update: to avoid a compiler warning about assigning a signed int
to unsigned
, use the below. This is an unsigned
1u
being negated - which is well defined as above. The effect is the same as a -1
, but conveys to the compiler direct intentions.
unsigned int a = -1u;
Upvotes: 34
Reputation: 5361
When you initialize unsigned int a to -1;
it means that you are storing the 2's
complement of -1
into the memory of a
.
Which is nothing but 0xffffffff
or 4294967295
.
Hence when you print it using %x or %u
format specifier you get that output.
By specifying signedness of a variable to decide on the minimum and maximum limit of value that can be stored.
Like with unsigned int
: the range is from 0 to 4,294,967,295
and int
: the range is from -2,147,483,648 to 2,147,483,647
For more info on signedness refer this
Upvotes: 0
Reputation: 13035
Having unsigned
in variable declaration is more useful for the programmers themselves - don't treat the variables as negative. As you've noticed, both -1
and 4294967295
have exact same bit representation for a 4 byte integer. It's all about how you want to treat or see them.
The statement unsigned int a = -1;
is converting -1
in two's complement and assigning the bit representation in a
. The printf()
specifier x
, d
and u
are showing how the bit representation stored in variable a
looks like in different format.
Upvotes: 0