0

I have a curiosity about unsigned char. I have a curiosity about unsigned char. I did a subtraction operation on unsigned char accidentally.I know i am not supposed to do that. But i am bit curious about how a particular answer came. Can anybody explain this at bit level?

unsigned char x = 150;
unsigned char y = 229;

unsigned char z = x - y;

finally i got 177 for z during the debugging

I am running this code in visual studio 2008.

Varo
  • 831
  • 1
  • 7
  • 16

2 Answers2

4

Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2^n where n is the number of bits in the value representation of that particular size of integer.

(C++11 standard, 3.9.1.5)

On most platforms an unsigned char is 8 bits, so the result is 150 - 229 mod 256 = -79 mod 256 = 177.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
1

Yes, if you subtract 229 from 150, you end up with -79. However, since you're limited to the range 0..255 (assuming 8 bits) because of the destination, it wraps around to ensure that range is maintained. Hence you basically add 256 to -79 to end up with 177.

In other words, 9 - 10 which would give you -1 in a signed value, actually gives you 255 for an 8-bit unsigned char. Similarly, 9 - 11 would give you 254.

It's no different to addition, with 255 + 7 giving you 6 because it wraps back to 0 following 255.

Now, the rules are a little more complex than that insofar as the values may be promoted to a larger data type, then the subtraction done, then the result truncated. But mathematically, that first paragraph is correct.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    Your reasoning only works if the type of `z` is an `unsigned char`. And the last part is completely wrong, operands to arithmetic operators undergo integral promotion *prior to* the the arithmetic operation being performed. [Here's an example](http://coliru.stacked-crooked.com/a/929ac351d5f62e99) of how this works. – Praetorian Jan 29 '14 at 04:35
  • 1
    As it turns out, `z` is an `unsigned char` after all, so the first part of your answer is correct. The last paragraph is still wrong, because integral promotion still applies. Arithmetic operators do not operate on anything smaller than an `int`. In practice, a compiler will probably see that the result is being placed into an `unsigned char` and not perform the promotions assuming the operation is more efficient on `char`s. – Praetorian Jan 29 '14 at 04:43