2

3 bits can hold up to a maximum number of 7 (4 + 2 + 1). I'm trying to calculate this using a bitwise operation.

3 is 0b011 
~3 is 0b100

Doing a bitwise OR I would expect 0b111 (i.e. 7). Instead I get

int result = (~3) | 3;
printf("%i\n", result);

-1

What am I doing wrong?

deltanovember
  • 42,611
  • 64
  • 162
  • 244
  • possible duplicate of [C bitwise negation creates negative output:](http://stackoverflow.com/questions/12084364/c-bitwise-negation-creates-negative-output) – jogojapan Apr 23 '13 at 02:41

5 Answers5

6

You are doing everything right: N | ~N results in a number with binary representation consisting of all ones. Such number is interpreted as -1 in two's compliment representation of negative numbers.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Yeah never mind, I just realized I was wrong and deleted the comment before you posted that comment. – Shoe Apr 23 '13 at 02:16
  • @modifiablelvalue `~3` is `111111..111100`, so the last three bits are indeed `0b100`. – Sergey Kalinichenko Apr 23 '13 at 02:21
  • @dasblinkenlight `3` is an integer literal of type `int`. The `~` operator isn't well defined for signed integers. – autistic Apr 23 '13 at 02:26
  • @modifiablelvalue: The bit-pattern of ~ is perfectly well defined for signed integers; it is each bit inverted. The interpretation of that value depends on whether the integers are one's complement, two's complement or sign and magnitude, but the same was true of the interpretation of the value of the integer before inversion. – Jonathan Leffler Apr 23 '13 at 11:21
  • @JonathanLeffler Please show me where the standard says that the sign bit is to be inverted... – autistic Jun 14 '13 at 13:00
  • 1
    @Undefined, 6.5.3.3/4 says "each bit in the result is set if and only if the corresponding bit in the converted operand is not set." Surely, the sign bit is part of the operand, no? – Rob Kennedy Sep 25 '13 at 13:28
4

How many bits wide is an int? You seem to think it's three bits wide. Certainly not correct! Guess again. What is ~0u? Try printf("%u\n", ~0u);. What about ~1u? ... and ~2u? Do you notice a pattern?

Note the u suffix, which tells the compiler that it's an unsigned literal. You can't work with signed integer types with the ~ operator... Well, you can, but you might run into trap representations and negative zeros, according to 6.2.6.2 of n1570.pdf. Using a trap representation is undefined behaviour. That might work on your system, but only by coincidence. Do you want to rely upon coincidence?

Similarly, I suggest using the %u directive to print unsigned values, as %d would produce undefined behaviour according to 7.21.6.1p29 of n1570.pdf.

autistic
  • 1
  • 3
  • 35
  • 80
  • 3
    @Jueecy.new Can you use questions to teach people/answer other questions? Read [The Socratic Method](http://www.garlikov.com/Soc_Meth.html). – autistic Apr 23 '13 at 02:29
  • 2
    [Nice question](http://meta.stackexchange.com/questions/177612/should-the-socratic-method-be-discouraged). – Shoe Apr 23 '13 at 11:09
0

When you do ~3 you are inverting the bits that make up 3 - so you turn 0000 0000 0000 0000 0000 0000 0000 0011 into 1111 1111 1111 1111 1111 1111 1111 1100. Since the high bit is set, this is interpreted as a negative number - all 1s is -1, one less than that is -2, one less -3 and so on. This number is the signed 32 bit integer for -4.

If you binary OR this with 3, you get all 1s (by definition) - which is the signed 32 bit integer for -1.

Your only problem is that you think you are working with 3 bit numbers, but you are actually working with 32 bit numbers.

Patashu
  • 21,443
  • 3
  • 45
  • 53
0

After doing this in the code

  int result = (~3) | 3;

Add this line

   result= result & 0x07

This will give you the answer that you expect.

Jay K
  • 1,087
  • 1
  • 10
  • 14
0
#include <stdio.h>

int main (){
    unsigned d3 = 0b011;
    unsigned invd3 = ~d3;
    unsigned d4 = 0b100;
    unsigned result = d3 | invd3;
    printf("%X\n", result);//FFFFFFFF
    result = d3 | d4;
    printf("%X\n", result);//7
    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70