Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

datatype promotion in c

Tags:

c

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!

like image 273
Dom045 Avatar asked Mar 04 '12 05:03

Dom045


People also ask

Is type promotion and type conversion same?

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.

What is integer promotion in C?

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.

Why does C have 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.

Can int be promoted to float?

Floating-point operands are not promoted like integer ones are: the expression 1. f + 1.


1 Answers

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.

like image 75
Mysticial Avatar answered Nov 12 '22 06:11

Mysticial