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

前端 未结 3 1764
暗喜
暗喜 2021-01-18 11:31
#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         


        
相关标签:
3条回答
  • 2021-01-18 12:04

    0x80000000 is a big number which needs 32 bit to represent that number. This means on a 32 bit system (or in a 32 bit compatible application) an int is too small. So use unsigned long instead:

    #define SCALE (1u << 31)
    
    #define fix_Q31_80(x) ( (unsigned long) ( (float)(x)*(float)0x80000000u ) )
    #define fix_Q31_SC(x) ( (unsigned long) ( (float)(x)*(float)SCALE       ) )
    
    int main()
    {
        unsigned long fix_80 = fix_Q31_80(0.5f);
        unsigned long fix_sc = fix_Q31_SC(0.5f);
    }
    
    0 讨论(0)
  • 2021-01-18 12:12

    All integer constants have a type. In the case of 1, the type is int. On a system with 32 bit integers, 1 << 31 gives a number which is too large to be represented as an int. This is undefined behavior and therefore a bug.

    But 0x80000000 will work as expected, because on a 32 bit system it happens to be the type unsigned int. This is because decimal constants and hexadecimal constants behave differently when the compiler goes looking for what type they should have, as explained here.

    As several people have mentioned, don't use bitwise operators on signed types.

    0 讨论(0)
  • 2021-01-18 12:13

    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.

    0 讨论(0)
提交回复
热议问题