Reputation: 1342
I would like to use an unsigned char
as a byte. I would expect that it would have a range from 0
to 255
.
I defined the following macro:
#define ROTATE_LEFT(BYTE) ((BYTE & 128) > 0) ? ((BYTE << 1) | 1) : (BYTE << 1)
I would like to rotate it to the left.
Now I tested it by:
unsigned char c1 = 1;
unsigned char c2 = 128;
unsigned char c3 = 255;
unsigned char c4 = 200;
printf("%u\n", ROTATE_LEFT(c1)); // Expected: 2, Result: 2
printf("%u\n", ROTATE_LEFT(c2)); // Expected: 1, Result: 257
printf("%u\n", ROTATE_LEFT(c3)); // Expected: 255, Result: 511
printf("%u\n", ROTATE_LEFT(c4)); // Expected: 145, Result: 401
As you can see, I get results that should't be even possible. What is wrong?
Upvotes: 3
Views: 420
Reputation: 6121
Just like this:
unsigned char c4 = 200;
printf("%u\n", c4 + 56);
output: 256
It's nothing to do with the unsigned char
type of c4
, you just pass a greater-than-255 value to printf
function.
Upvotes: 0
Reputation: 137467
This because of integer promotion.
Your results are bring promoted to larger integers before being passed to printf.
You could store the result back into your variable, before passing that variable to printf. They will necessarily be truncated.
Also, the printf
specifier for an unsigned char
is %hhu
.
Finally, I would suggest the following (untested) instead:
static inline uint8_t rol8(uint8_t x)
{
uint8_t low = (x & (1<<7)) >> 7;
return (x << 1) | low;
}
Upvotes: 10