Home > Back-end >  How do I resolve the following error in my bit shifting C code?
How do I resolve the following error in my bit shifting C code?

Time:12-04

Can anyone help me with the below? Say I have the binary value int colour which is 255 or i.e.

00000000 00000000 000000000 11111111

in binary. How can I perform shifting to get

11111111 11111111 11111111 00000000

I tried making 4 values of 0xff, 0xff00, 0xff0000, 0xff000000 and was going to OR them but when I print these values out I get the following error:

converter.c:66:23: runtime error: left shift of 255 by 24 places cannot be represented in type 'int'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior converter.c:66:23 

in 
VALS ARE ff,  ff00, ff0000, ff000000

Below is my code any help would be greatly appreciated

  int val1 = colour;
  int val2 = (colour << 8);
  int val3 = (colour << 16);
  int val4 = (colour << 24);
  //unsigned int val5 = 0;
  printf("VALS ARE %x,  %x, %x, %x\n" , val1, val2, val3, val4);
  //rowElement(colour, sketch);

CodePudding user response:

You're getting an error because you're shifting a value into the sign bit of an int. If you shift a 1 into that bit, you trigger undefined behavior.

This is described in section 6.5.7p4 of the C standard regarding bitwise shift operators:

The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

Change the type of each of your variables to unsigned int. Then you can freely shift into any of the bits, as long as you don't shift by 32 bits or more, assuming an int is 32 bits.

CodePudding user response:

It is enough to write

int x = 255;
x ~= x;

Or it will be better to declare the variable x as having the type unsigned int.

unsigned int x = 255;
x ~= x;

As for the shift operator then according to the C Standard (6.5.7 Bitwise shift operators)

4 The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.

CodePudding user response:

To reverse the bytes in ARGB color or any 32-bit unsigned integer, shift to the right, then AND with 0xff For example, to get 44 from 0x11223344 we need just 0x11223344 & 0xff To get 33, shift right by 8 bits -> 0x00112233 and then AND with 0xff again.

Left-shift is needed to build a 32-bit integer again.

int main(void)
{
    unsigned int colour = 0x11223344;

    unsigned char byte0, byte1, byte2, byte3;
    byte0 = (colour      ) & 0xff;
    byte1 = (colour >> 8 ) & 0xff;
    byte2 = (colour >> 16) & 0xff;
    byte3 = (colour >> 24) & 0xff;

    unsigned int reversed = byte0 << 24 | byte1 << 16 | byte2 << 8 | byte3;

    printf("X\n", colour);
    printf("X\n", reversed);

    return 0;
}

Output

11223344
44332211
  • Related