Question

I knew that ~ operator does NOT operation. But I could not make out the output of the following program (which is -65536). What exactly is happening?

#include <stdio.h>

int main(void) {
  int  b = 0xFFFF;
  printf("%d",~b);
  return 0;
}
Was it helpful?

Solution 2

When you assign the 16-bit value 0xffff to the 32-bit integer b, the variable b actually becomes 0x0000ffff. This means when you do the bitwise complement it becomes 0xffff0000 which is the same as decimal -65536.

OTHER TIPS

Assuming 32-bit integers

int  b = 0xFFFF; => b = 0x0000FFFF
~b = 0xFFFF0000

The top bit is now set. Assuming 2s complement, this means we have a negative number. Inverting the other bits then adding one gives 0x00010000 or 65536

It is doing a bitwise complement, this output may help you understand what is going on better:

std::cout <<  std::hex << " b: " << std::setfill('0') << std::setw(8) <<  b
           << " ~b: " <<  (~b) << " -65536: " << -65536 << std::endl ;

the result that I receive is as follows:

b: 0000ffff ~b: ffff0000 -65536: ffff0000

So we are setting the lower 16 bits to 1 which gives us 0000ffff and then we do a complement which will set the lower 16 bits to 0 and the upper 16 bits to 1 which gives us ffff0000 which is equal to -65536 in decimal.

In this case since we are working with bitwise operations, examining the data in hex gives us some insight into what is going on.

The ~ operator in C++ is the bitwise NOT operator. It is also called the bitwise complement. This is flipping the bits of your signed integer.

For instance, if you had

 int b = 8;
 // b in binary = 1000
 // ~b = 0111

This will flip the bits that represent the initial integer value provided.

The result depends on how signed integers are represented on your platform. The most common representation is a 32-bit value using "2s complement" arithmetic to represent negative values. That is, a negative value -x is represented by the same bit pattern as the unsigned value 2^32 - x.

In this case, the original bit pattern has the lower 16 bits set:

0x0000ffff

The bitwise negation clears those bits and sets the upper 16 bits:

0xffff0000

Interpreting this as a negative number gives the value -65536.

Usually, you'll want to use unsigned types when you're messing around with bitwise arithmetic, to avoid this kind of confusion.

Your comment:

If it is NOT of 'b' .. then output should be 0 but why -65536

Suggests that you are expecting the result of:

uint32_t  x = 0xFFFF;
uint32_t y = ~x;

to be 0.

That would be true for a logical not operation, such as:

uint32_t x = 0xFFFF;
uint32_t y = !x;

...but operator~ is not a logical NOT, but a bitwise not. There is a big difference.

A logical returns 0 for non-0 values (or false for true values), and 1 for 0 values.

But a bitwise not reverses each bit in a given value. So a binary NOT of 0xF:

0x0F:  00000000 11111111
~0x0F: 11111111 00000000

Is not zero, but 0xF0.

For every binary number in the integer, a bitwise NOT operation turns all 1s into 0s, and all 0s are turned to 1s.

So hexadecimal 0xFFFF is binary 1111 1111 1111 1111 (Each hexadecimal character is 4 bits, and F, being 15, is full 1s in all four bits)

You set a 32 bit integer to that, which means it's now:

0000 0000 0000 0000 1111 1111 1111 1111

You then NOT it, which means it's:

1111 1111 1111 1111 0000 0000 0000 0000

The topmost bit is the signing bit (whether it's positive or negative), so it gives a negative number.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top