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?

1

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Yeah never mind, I just realized I was wrong and deleted the comment before you posted that comment.
@modifiablelvalue ~3 is 111111..111100, so the last three bits are indeed 0b100.
@dasblinkenlight 3 is an integer literal of type int. The ~ operator isn't well defined for signed integers.
@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.
@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?
|
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.

2 Comments

@Jueecy.new Can you use questions to teach people/answer other questions? Read The Socratic Method.
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.

Comments

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.

Comments

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; } 

2 Comments

You need to add some description with this answer ;-)
@SandipArmalPatil I don't think necessary.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.