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