Integer Promotions in C
As we know that some of the data types such as char, short int, Enum takes a smaller number of bytes than compared to int. When an operation is applied to these char, Enum and short int data type, these are directly further encouraged to unsigned int. Such type of promotion is known as integer promotion.
Example: When any operation is applied on short int, char, Enum like arithmetic as we know these takes lesser number of bytes, so this is firstly converted into an int or unsigned int. If int represents all original type values, then it is converted into int else the value is converted into unsigned int.
Code:
#include<stdio.h>
int main ()
{
char a=20, b=30, c=10;
char d=(a*b)/c;
printf (“%d”, d);
return 0;
}
Output:
60
As we know that the signed char takes values from -128 to 127 and from the above given expression that is “(a*b)/c” appears to happen arithmetic flow but the result is 600 which is greater than 128 so, integer promotion happens in this case, and we get appropriate result without overflow.
Example:
#include<stdio.h>
int main ()
{
Char a = 0xfb;
unsigned char b = 0xfb;
printf (“a = %c”, a);
printf (“\nb = %c”, b);
if(a==b)
printf(“\nsame”);
else
printf (“\nNot Same”);
return 0;
}
Output:
Not Same
From the above code the results of ‘a’ and ‘b’ is “Not Same” because at the time of comparison they both are converted into int , but ‘a’ is assigned to signed char so 0xfb becomes -5 and ‘b’ is assigned to unsigned char and it takes the value 251 as they have different values , so the result is “Not Same”.
Note:
1. Unsigned and signed char rank should always equal to char rank.
2. There should be equal ranks for unsigned char and any singed int type.
3. Extended int rank must always be smaller than standard int rank.
Arithmetic Conversions
If an operation consists of two operands, it is known as binary. When a binary operation is applied the two operands must have same type, if it is different, C impose implicit conversion to operand one and its type to other.
- If long double is the type of each of the two operands then without any changes of domain, the next operand is also converted into long double type.
- If double is the type of each of the two operands then without any changes of domain, the next operand is also converted into double type.
- If float is the type of each of the two operands then without any changes of domain, the next operand is also converted into float type.
Else when integer promotions are applied on both operands then the rules are:
- If two of them have same type then changes are not needed.
- If both operands contain signed or unsigned int then the operand with smaller rank must be changed into operand with the higher rank.
- If the operand is of unsigned type and rank is higher or equals to another type then that operand which is singed int must be changed to operand with type of unsigned int.
Example:
int main ()
unsigned char x =0;
unsigned char y = 1;
printf (“%u\n”, x-y);
printf (“%d\n”, x-y);
}
As int is higher than unsigned char so integer promotion applies on the code therefore, int (x) – int (y) = int (-1) and the value of unsigned (-1) is 42949697295.
Output:
424967295
-1
From the above code changing one to an unsigned int
int main ()
unsigned int x=0;
unsigned char y=1;
printf (“%u\n”, x-y);
printf (“%d\n”, x-y);
}
As x is unsigned int, integer promotions apply to y then we obtain (unsigned int) x – (int) y, we can see the data types are still not same arithmetic conversions applies here, therefore we obtain:
(unsigned int) x – (unsigned int) y = 4294967295
Output:
4294967295
-1
Likewise, the upcoming code results to the same output:
int main ()
unsigned char x =0;
unsigned int y=1;
printf (“%u\n”, x-y);
printf (“%d\n”, x-y);
}
By changing either of them into unsigned, we obtain the following code:
int main () {
unsigned int x =0;
unsigned int y=1;
printf (“%u\n”, x-y);
printf (“%d\n”, x-y);
}
As each of them are unsigned int, integer promotions do not apply, and the output is:
4294967295
-1
We can set the code in the following way:
int main ()
unsigned char x =0;
unsigned char y=1;
printf (“%u\n”, x-y);
printf (“%d\n”, x-y);
unsigned char z = x-y;4
printf (“%u\n”, z);
}
Output:
4294967295
-1
255