Search code examples
cbitwise-operatorsbit-shiftinteger-promotion

Fixed point arithmetic long long int representation issue in C


I am struggling with the realization of a signed long long int variable having the value 1 set in its integer part. Looking at the 16.16 implementation with a signed long int variable it does work like this:

static signed long int varInit = 1 << 16; /* alternatively: 65536 */
unsigned short int integer_part,fractional_part;
fractional_part = ((unsigned short int *) &varInit)[0];
integer_part = ((unsigned short int *) &varInit)[1];

This leads to the following representation: 0001.0000

Unfortunately I cannot get it to work in the 32.32 representation:

static signed long long int varInit = 1 << 32;
unsigned long int integer_part,fractional_part;
fractional_part = ((unsigned long int *) &varInit)[0];
integer_part = ((unsigned long int *) &varInit)[1];

I get the following gcc warning: warning: left shift count >= width of type

What am I getting wrong?

I am trying to get the following representation: 00000001.00000000


Solution

  • This expression

    1 << 32
    

    has undefined behavior because the operands have the type int and the result also has the type int.

    From the C Standard (6.5.7 Bitwise shift operators)

    3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined

    At least use the expression

    1LL << 32