Implicit Type Conversion in C

As already discussed we can mix different kinds of data types and constants in an expression. In such expressions operand of one data type is converted to another data type. This process is known as Type Conversion.

There are two types of type conversion:

  1. Implicit type conversion.
  2. Explicit type conversion.

Implicit type conversion

This type of conversion is done by the compiler according to the following rules:

  1. All operands of type char or short will be converted to int before any operation and the result will be in int  too.
  2. If one operand is of type long double, then the other operand will be converted to long double  and then the result will be in long double too.
  3. Otherwise, If one operand is of type double then the other operand will be converted to double and the result will be in double.
  4. Otherwise, If one operand is of type float then the other operand will be converted to float and the result will be in float.
  5. Otherwise, If one operand is of type unsigned long int then the other operand will be converted to unsigned long int and the result will be in unsigned long int.
  6. Otherwise, If one operand is of type long int then the other operand will be converted to long int and the result will be in long int.
  7. Otherwise, If one operand is of type unsigned int then the other operand will be converted to unsigned int and the result will be in unsigned int.
  8. Otherwise, If one operand is of type int then the other operand will be converted to int and the result will be in int.

Let's take some examples to make everything clear.

Example 1:

int a = 100;
double b = 12.5;

a + b;

Here one operand is of type int and other is of type double. Therefore according to rule 3, the variable a will be converted to double. Hence the result of the overall operation is double i.e 112.500000.

Example 2:

char ch = 'a';
int a = 10;

a + c;

Here according to rule 1, char will be converted to int  before any operation and the result of the overall expressions will be of type int. Since the integral value of ch is 97 (i.e ASCII value of the character 'a' ). Hence 97 + 100 = 197.

Example 3:

char ch = 'A';
unsigned int a = 10;

a * b;

Here according to rule 7, variable ch of type char will be first converted to unsigned int i.e 65 (ASCII value of 'A' ), before addition will be carried out. And the result of the whole operation will be an unsigned int . Hence 65 + 10 = 75.

Here are some more examples:

char ch;
short int si;
int i;
unsigned int ui;
float f;
long double ld;

i = ch + si;    //   both ch and si will be converted to int before addition
i = si + i;    //   si will be converted to int before addition
ui = i + ui;   //   i will be converted to unsigned int before addition
f = ui + f;   // ui will be converted to usigned int before addition
ld = f + ld;    // f will be converted ti long double before addition

All the above-mentioned rules can be simplified by assigning a rank to each type. Here is how it works.

Whenever two operands of different data types are involved in an expression, the operand of lower rank will be converted to a data type of higher rank. This process is called the promotion of type.

Type Conversion in assignment

If types of the operand in an assignment expression is different, then the operand on the right-hand size will be converted to the type of left-hand operand according to the following rules.

1. If types of the operand in an assignment expression is different, then the operand on the right-hand size will be converted to the type of left-hand operand according to the following rules.

If the right-hand operand is of lower rank then it will be promoted to the rank of left operand.Let's take an example:

int i = 'z';

here right operand 'z' is of type char and the right-hand operand is of type int. According to rule lower rank operand (in this case char) will be promoted to a higher rank (in this case int). So before assignment 'z'  i.e 122 ( ASCII value )  will be promoted to int and then assigned to i.

2. Otherwise, if right-hand operand is of higher rank then it will be demoted to the rank of left-hand operand. For example:

float a = 120.33;

Recall that by default floating point constants are of type double. In this case, right-hand operand i.e 120.33 is of type double and the left-hand operand is of type float. Therefore before assignment operation 120.33 will be demoted to float type and then the assignment will take place.

Some consequences of type conversion in assignment are:

1. High order bits may be lost when long int is converted to int or int to short int or int to char. Let's take an example to understand this point clearly. Suppose we have the following statement.

unsigned char ch = 257;

Here we are trying to assign 257 (int type) to a char variable. According to type conversion rules: data type of higher rank will be converted to data type lower rank. But there is a problem, recall that unsigned char type can only take values from 0 to 255. Cleary 257 is out of range for variable ch. In such cases, an appropriate value from the other side of the range is picked up and stored in ch. So eventually what gets stored inch  variable is a smiley character having ASCII value 2.

2. Fractional part will be truncated during conversion from floating point type ( like double , float ) to int type.

3. When the double type is converted to float type digits are rounded off.

4. When int  is converted to float or float to double there is not increase in accuracy.

5. When signed type is changed to unsigned type, the sign may be dropped.

The following example demonstrates how type conversion takes place.

#include<stdio.h>

int main()
{
    float f_val1 = 97.12, f_val2;
    int i_val1, i_val2;
    char ch_val1, ch_val2;

    // float is demoted to int, only 97 is assigned to i_val1
    i_val1 = f_val1;

    // int is demoted to char,
    ch_val1 = i_val1;

    // float is demoted to int, only 12 is assigned to i_val2
    i_val2 = 12.45f;

    // char is promoted to int, now
    // i_val1 contains ASCII value of character 'e' i.e 101
    i_val2 = 'e';

    /*
        double is demoted to float, since by
        default floating point constants
        are of type double
    */

    f_val2 = 12.34;

    // Print the value of i
    printf("Value of i_val1 = %d\n", i_val1);

    // Print the character corresponding to ASCII value 97
    printf("Value of ch_val1 = %c\n", ch_val1);

    // Print the ASCII value of character 'e'
    printf("Value of i_val2 = %d\n", i_val2);

    // Print f_val2 with 2 digits of precision
    printf("Value of f_val2 = %.2f\n", f_val2);

    // Signal to operating system everything works fine
    return 0;
}

Expected Output:

Value of i_val1 = 97
Value of ch_val1 = a
Value of i_val2 = 101
Value of f_val2 = 12.34