Hey I am kinda new to C and I wanted to ask why this prints out 4
instead of 260
?
#include <stdio.h>
int main()
{
unsigned char x = 130;
x *= 2;
printf("%d\n", x);
}
Hey I am kinda new to C and I wanted to ask why this prints out 4
instead of 260
?
#include <stdio.h>
int main()
{
unsigned char x = 130;
x *= 2;
printf("%d\n", x);
}
The *=
operator is called multiplication assignment operator and is shorthand for multiplying the operand to the left with the operand to the right and assigning the result to the operand to the left. In this case, it's the same as:
x = x * 2;
Here integer promotion first takes place and the result of x * 2
is indeed 260
.
However, an unsigned char
can usually only carry values between 0 and 255 (inclusive) so the result overflows (wraps around) when you try assigning values above 255 and 260 % 256 == 4.
x *= 2
uses the multiplication assignment operator, a short hand notation for x = x * 2
where x
is only evaluated once.
The behavior of this small program is non trivial:
x
, 130
is promoted to type int
and the multiplication gives 260
as an int
.unsigned char
by repeatedly subtracting UCHAR_MAX+1
, which is 256 on your system, until reaching a value in the range of the destination type. Hence x
becomes 260 % 256 = 4.int
, x
is promoted to int
when passed to printf
, so the format %d
, which expects an int
value, has defined behavior and produces 4
.Note that for exotic architectures (eg: digital signal processing chips) where unsigned char
has more than 8 bits, some of the above discussion is irrelevant and the printf
may print 260
or even have undefined behavior (if sizeof(int) == 1
).
According to language specification unsigned char data type takes 1 byte of memory so it can store values 0-255 and if you a value greater than 255 it will overflow beginning from zero. So 260(130 * 2) - 256 = 4 is assigned to your variable. https://learn.microsoft.com/en-us/cpp/cpp/cpp-type-system-modern-cpp?view=msvc-170#fundamental-built-in-types
In the statement with the compound assignment operator
x*=2;
that is equivalent to
x = x * 2;
the operand x
of the expression is converted to the type int
due to the integer promotions and the result pf the expression is indeed equal to 260. But the result is assigned to the variable x that has the type unsigned char.
unsigned char x=130;
The value 260 can not be stored in such an object. As 260 is internally as an integer is represented like
0x00000104
then only the last byte having the value 0x4 is stored in the object and this value is outputted.
You could get the expected result if for example the type of the variable x would be changed at least like
unsigned short x=130;
The unsigned char
can contain only from 0 to 256. When the value is over 256, the value is forced from 0 to 256.