2

I got

uint32_t bits = 0;

bits |= 1<< 31;
bits |= 1<< 15;
bits |= 1<< 14;
bits |= 1<< 13;

which gives me 10000000000000001110000000000000

and in another function I do *(bits) |= 0 << 15; but it doesn't do anything, it should change the 16th 1 to a 0, so the following should come: 10000000000000000110000000000000

any help?

codeoverflow
  • 143
  • 2
  • 12
  • 2
    `0 << 15` is `0`. No matter how many times you shift `0` to the left or right, you always end up with `0`. – Hristo Iliev Nov 15 '13 at 13:25
  • Is the dereferencing in `*(bits) |= 0 << 15;` supposed to be there? Is the second `bits` not of type `uint32_t`? Reading through the question and answers this inconsistency seems a bit confusing although irrelevant to the problem. –  Dec 26 '13 at 14:14

3 Answers3

5

The correct way to change a bit to 0 is to and the negation, e.g.

bits &= ~(1 << 15);
dornhege
  • 1,500
  • 8
  • 8
1

You have to do:

bits &= ~(1 << 15)
Sergey K.
  • 24,894
  • 13
  • 106
  • 174
1

Clearing a bit is done by AND-ing with the complement, i.e.:

*(bits) &= ~(1 << 15);

(1 << 15) produces a number with bit 15 set to 1:

00000000000000001000000000000000

then the bitwise NOT operator inverts this and produces a number that is all ones except bit 15:

11111111111111110111111111111111

When you AND this number to the original one, the bit in position 15 is cleared:

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
               &
11111111111111110111111111111111
================================
XXXXXXXXXXXXXXXX0XXXXXXXXXXXXXXX

where X marks the original bits.

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186