yemerra
yemerra

Reputation: 1342

Usigned char goes over 255

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

Answers (2)

Van Tr
Van Tr

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

Jonathon Reinhart
Jonathon Reinhart

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

Related Questions