In the following code:
#include "stdio.h"
signed char a= 0x80;
unsigned char b= 0x01;
void main (void)
{
if(b*a>1)
printf("promoted\n");
else if (b*a<1)
printf("why doesnt promotion work?");
while(1);
}
I expected "promoted' to be printed. But it doesnt. Why? If I can the datatypes to signed and unsigned int, and have a as a negative number, eg, 0x80000000 and b as a positive number, 0x01, "promoted" gets printed as expected.
PLZ HELP me understand what the problem is!
It means converting one data type into another. Converting smaller data type into a larger one is also called as type promotion. There are two type of type conversion: implicit and explicit type conversion in C. Implicit type conversion operates automatically when the compatible data type is found.
Some data types like char , short int take less number of bytes than int, these data types are automatically promoted to int or unsigned int when an operation is performed on them. This is called integer promotion.
There are some data types which take less number of bytes than integer datatype such as char, short etc. If any operations are performed on them, they automatically get promoted to int. This is known as integer promotions.
Floating-point operands are not promoted like integer ones are: the expression 1. f + 1.
You've just been caught by the messy type-promotion rules of C.
In C, intermediates of integral type smaller than int
are automatically promoted to int
.
So you have:
0x80 * 0x01 = -128 * 1
0x80
gets signed extended to type int
:
0xffffff80 * 0x00000001 = -128 * 1 = -128
So the result is -128
and thus is less than 1
.
When you use type int
and unsigned int
, both operands get promoted to unsigned int
. 0x80000000 * 0x01 = 0x80000000
as an unsigned integer is bigger than 1
.
So here's the side-by-side comparison of the type promotion that's taking place:
(signed char) * (unsigned char) -> int
(signed int ) * (unsigned int ) -> unsigned int
(signed char)0x80 * (unsigned char)0x01 -> (int) 0xffffff80
(signed int )0x80000000 * (unsigned int )0x01 -> (unsigned int)0x80000000
(int) 0xffffff80 is negative -> prints "why doesnt promotion work?"
(unsigned int)0x80000000 is positive -> prints "promoted"
Here's a reference to the type-promotion rules of C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With