Question

I have a simple application:

#include <stdio.h>

int main(int argc, char **argv)
{
  unsigned int a = 0x2; //= 10b
  unsigned int b = ~a;  // should be 01b
  printf("%04x : %04x\n", a, b);
}

I wonder, why does it print 0002 : fffffffd instead of 0002 : 0001?

Was it helpful?

Solution 2

Basically, you're right. However an unsigned integer is (usually) 32 bits long (on a 32 bit system).

So you're not only flipping the last two bits but the 30 bits before as well.

To solve this, you'll just have to mask the bits you're interested in:

#include <stdio.h>

int main(int argc, char **argv)
{
    unsigned int a = 0x2;       //= 10b
    unsigned int b = ~a & 0x3;  //= 01b (0x3 = 11b)
    printf("%04x : %04x\n", a, b);
}

OTHER TIPS

fffffffd(hex) -> 11111111111111111111111111111101(binary)
00000002(hex) -> 00000000000000000000000000000010(binary)

As you can see, they ARE bitwise negations of each other.

02x is an integer constant. On a 32-bit system that corresponds to 0x00000002, only with insignificant zeros omitted. When you invert that value, you get back 0xfffffffd - precisely the value that you see.

If you want to keep only the last two bits, mask with 0x03, like this:

unsigned int b = ~a & 0x03;  // will be 01b

Demo on ideone.

This is because 2 is represented in binary o(on 32 bit machine) as

00000000000000000000000000000010  

and its bitwise NOT is

11111111111111111111111111111101 

which is equivalent to fffffffd in hex.

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