Home > Mobile >  Incorrect bitwise result
Incorrect bitwise result

Time:10-25

I'm working on a C project for a PIC microcontroller in MikroC and have a function:

void Write_SPI_32(unsigned long Address, unsigned long Data);

That only sometimes works:

Write_SPI_32(0x300000   12, 0b10001111000010100000000000000000);     //Gives expected result
Write_SPI_32(0x300000   12, 0x8f0a0000);                             //Gives expected result
Write_SPI_32(0x300000   12, 2399797248);                             //Gives expected result
Write_SPI_32(0x300000   12, (2 << 30) | (120 << 21) | (160 << 12));  //Gives UNEXPECTED result

How am I managing to noob the bitwise math here?

CodePudding user response:

2 << 30 overflows a 32-bit int, as the nominal result would be 231, but the largest value representable in int would be 231−1, so the behavior is not defined by the C standard.

A typical behavior from a compiler would be that this produces the result −231 (the same bit pattern as 231 but interpreted with two’s complement), then the other operands (120 << 21 and so on) are ORed in. Then, when the argument is converted to a 64-bit unsigned long to pass to Write_SPI_32, this negative int becomes an unsigned long with its high 32 bits set.

You can use (unsigned long) 2 << 30 or 2ul << 30. When shifting, it is often useful to cast the left operand to the ultimate destination type, so that the shift is performed in that type instead of in the default type that results from the integer promotions.

  • Related