3

I do not see why 3 & 0x1111 = 1 ? It seems that:

for any unsigned 32-bit integer i, i & 0x1111 should be i, right?

However when I tried this on ubuntu 14.04, I got 3 & 0x1111=1. Why?

int main() {
  unsigned int a =3;
  printf("size of a= %lu\n",sizeof(a));
  printf("value of 3 & 0x1111= %d\n",a & 0x1111);

  return 0;
} 
zell
  • 9,830
  • 10
  • 62
  • 115
  • 3
    for any unsigned 32-bit integer i, i & 0xffffffff should be i – cerkiewny Aug 27 '15 at 16:29
  • you are only masking the first bit so it is normal to become 1 – Nasr Aug 27 '15 at 16:30
  • 1
    @cerkiewny: For any `uint16_t`, but ot for a 32 bit type. `0xFFFF` is 16 `1`-bits only. – too honest for this site Aug 27 '15 at 16:32
  • 7
    Are you confusing hexadecimal and binary _integer-constants_? – too honest for this site Aug 27 '15 at 16:32
  • @Olaf. That is exactly what was happening :) – zell Aug 27 '15 at 16:33
  • Another note: You want 8 hex chars to make a 32-bit number. OR:ing with 0xffff will give you identity for 16-bit numbers. For 32-bit numbers, you need 0xffffffff. – Snild Dolkow Aug 27 '15 at 16:35
  • @SnildDolkow That makes sense. I need to revise K&R :) – zell Aug 27 '15 at 16:36
  • @SnildDolkow: **OR**-ing with `~0` (all bits 1) yields `~0`, not identity. You mean AND-ing – too honest for this site Aug 27 '15 at 16:36
  • Yeah, sorry. Too late to edit the comment, though. :/ – Snild Dolkow Aug 27 '15 at 16:40
  • @olaf Btw, how can I control the number of bits of ~0? It seems that using ~0 is a more viable way than 0xffffffff? – zell Aug 27 '15 at 16:42
  • to [print `size_t`](http://stackoverflow.com/q/940087/995714) which is the result of `size_of`, use `%zu`. Using the wrong format invokes undefined behavior http://stackoverflow.com/q/2524611/995714 – phuclv Aug 27 '15 at 16:52
  • @zell: If you need a certain bit-width, you should use `~(uint32_t)0`. This will yield exactly 32 1-bits in the LSBs of the "larger type: `int`, `unsigned` or `uint32_t`, according to the [integer promotions](http://port70.net/~nsz/c/c11/n1570.html#6.3.1.1p1), one of the more nasty (for the unaware) properties of C). `~0` will yield an `int` actually, I should have written `~0U`. Note that you can use any other `stdint.h` types (**never** rely on the standard C types to have a specific bit-width). Note that for signed types, things become more complicated. – too honest for this site Aug 27 '15 at 16:55
  • @zell: Read the [standard](http://port70.net/~nsz/c/c11/n1570.html#6.4.4.1p5) which type are used for integer constants. The link is the current C standard (C11) and a good reading anyway. – too honest for this site Aug 27 '15 at 17:01

6 Answers6

17

Convert both of them to binary:

0x1111 = 0001 0001 0001 0001
3      = 0000 0000 0000 0011

When you & them bit by bit, what else do you expect?

Code Different
  • 90,614
  • 16
  • 144
  • 163
  • I see. My bad. I kinda confused 1 and f :) – zell Aug 27 '15 at 16:31
  • And if you want to write in binary instead of hex, you can do that: 0b1111111111111111 == 0xffff (but note that this is only 16 bits -- a 32-bit integer would have 8 hex digits). – Snild Dolkow Aug 27 '15 at 16:34
  • 1
    It's a bit frightening to see what the vote differential is between two answers posted that were literally seconds away from each other. Nevertheless, it's still a good answer :) – rayryeng Aug 27 '15 at 16:42
7

In C, any numeric literal starting with 0x is a hexadecimal number. So the bitmask you are using is 1111 in hexadecimal. In the mask, bits #0, #4, #8 and #12 are 1s, and the rest are 0s. That's why you're getting 1.

0x1111 = 0000 0000 0000 0000 0001 0001 0001 0001 in binary
     3 = 0000 0000 0000 0000 0000 0000 0000 0011 in binary
------------------------------------------------
     1 = 0000 0000 0000 0000 0000 0000 0000 0001 after doing biwise AND

If you want to construct a mask with all 1s, in hex, it should be

0xffffffff = 1111 1111 1111 1111 1111 1111 1111 1111
Sufian Latif
  • 13,086
  • 3
  • 33
  • 70
4

3d = 3h = 11b

1111h = 0001000100010001b

so:

  0001000100010001b
&               11b
-------------------
                  1b
dbush
  • 205,898
  • 23
  • 218
  • 273
3

0x1111 is 0001000100010001 in binary. So 0x1111 & 3 is 0001000100010001 & 0000000000000011 = 0000000000000001

Eugene Sh.
  • 17,802
  • 8
  • 40
  • 61
2

0x1111 is 4369, or as binary: 0001000100010001 So, 3 (0011) masked against that is going to be 0001. Similarly, 19 (0001011) would be 17 (00010001)

Rowland Shaw
  • 37,700
  • 14
  • 97
  • 166
1

The & operator applies the binary and. The 0x means hexadecimal not binary so if we write 0x1111 into a binary we will get: 0001 0001 0001 0001 binary. 3 binary is 011

and

0001 0001 0001 0001 & 
0000 0000 0000 0011 =
0000 0000 0000 0001 = 1
cerkiewny
  • 2,761
  • 18
  • 36