Search code examples
cbinarybitnegative-number

Why (-7 << 16) | 75 has some extra bits?


I have a problem where some additional bits are being set in a number:

void print2_helper(int x) {
  int isodd = x%2 != 0;
  x /= 2;
  if (x)
    print2_helper(x);
  putchar('0' + isodd);
}
printf("-7 << 16: ");
print2_helper((-7 << 16));

printf("\n(-7 << 16) | 75: ");
print2_helper((-7 << 16) | 75);
puts("\n");

Output:

-7 << 16: 1110000000000000000
(-7 << 16) | 75: 1101111111110110101

Why doing simple |75 produces such a weird number full of ones?


Solution

  • (-7 << 16) | 75 yields a negative value and print2_helper doesn't work correctly on negative values as others pointed out.

    x /= 2 is not equivalent to shift right on negative integers. Lets examine how it results when x=-3 (we are using 5-bit integer for brevity)

    11101 = -3

    -3 / 2 = -1

    -1 is 11111 in binary representation which is not expected result (01110).

    Using unsigned integer argument on print2_helper should fix problem. (Together with fixing the issue PSKocik already mentioned in comments, which could be done by adding u suffix to make it unsigned integer: (-7u << 16) | 75)