0

Quite a few similar questions have been asked, but it still baffles me how

unsigned int a = -1;
int b = ~0;
if (a == b)
    printf("%u\t%d", a, b);

returns

4294967295 -1

I understand how the values are stored in C and why it displays those numbers, but my question is, how is a==b returning true here?

MD XF
  • 7,860
  • 7
  • 40
  • 71
Paulo
  • 325
  • 3
  • 16
  • 2
    I added the C tag since you appear to be using it. – Tim Biegeleisen Dec 03 '16 at 07:01
  • Why it's different from the question in the link above, is that the unsigned variable is initialized as `-1` - a negative value. The question here is about the comparison – Paulo Dec 09 '16 at 04:38

1 Answers1

3

By rules of mixed signed-unsigned comparisons, a == b is equivalent to a == (unsigned) b, i.e. the comparison is performed in the domain of unsigned type.

The result of ~0 is all-ones bit pattern. In signed integer type this pattern represents -1 on a 2's-complement platform. Which means that you initialized your b with -1 (as confirmed by your printf).

So, your comparison is effectively (unsigned) -1 == (unsigned) -1. No wonder it holds true.

But keep in mind that the equality is still implementation-dependent, since it depends on the properties of 2's-complement representation. As long as C language officially supports alternative signed integer representations (sign and magnitude, 1's-complement) the equality will depend on it.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Rather saying the comparison is performed in the domain of unsigned type, you should say the comparaison is made bit by bit. In fact, in hexadecimal a is equal to 0xFFFFFFFF (32 bit platform) mathematically -1 = (-2^31 + 2^31 - 1) =(0xFFFFFFFF) in 2s complement representation. And b = ~0 makes all bit to be set to 1 that gives in hexadecimal b = 0xFFFFFFFF. That explains the if condition returning true. – shamba Dec 03 '16 at 07:59
  • @shamba: Absolutely not! Quite the opposite, C language makes comparison in accordance with the rules of C language, not "bit by bit". There's are no "bit by bit" comparisons in C. In this case we kinda got lucky because we use 2's-complement machines, where signed `~0` produces `-1`. On a 1's-complement machine `~0` would not have produced `-1` (`0xFFFFFFFF` is "negative zero" there) and the equality would not hold, even though the underlying raw representations would still match "bit by bit". – AnT stands with Russia Dec 03 '16 at 08:06
  • @AnT can you put in a reference to some material? with reference to the comparison being equated to `(unsigned) -1 == (unsigned) -1`. I understand how b becomes -1, already knew it, but the comparison? – Paulo Dec 09 '16 at 04:38