Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining (1 << 31) or using 0x80000000? Result is different

Tags:

c

casting

#define SCALE (1 << 31)

#define fix_Q31_80(x) ( (int) ( (float)(x)*(float)0x80000000 ) )
#define fix_Q31_SC(x) ( (int) ( (float)(x)*(float)SCALE      ) )

int main()
{
    int fix_80 = fix_Q31_80(0.5f);
    int fix_sc = fix_Q31_SC(0.5f);
}

Why are the values fix_80 and fix_sc different?

fix_80 == Hex:0x40000000
fix_sc == Hex:0xc0000000
like image 991
Danijel Avatar asked Jan 18 '17 10:01

Danijel


1 Answers

1 << 31 is undefined behavior on most platforms (e. g., systems with 16-bit or 32-bit int) as its result cannot be represented in an int (the resulting type of the expression). Don't use that expression in code. On the other hand 1U << 31 is a valid expression on systems with 32-bit int as its result is representable in an unsigned int (the resulting type of the expression).

On a 32-bit int system, 0x80000000 is a (relatively) big positive integer number of type unsigned int. If you are lucky (or unlucky) enough to not have demons to fly out of your nose by using 1 << 31 expression, the most likely result of this expression is INT_MIN which is a (relatively) big negative integer number of type int.

like image 99
ouah Avatar answered Oct 03 '22 23:10

ouah