0

I've been running through the logic of clearing bits and I don't really understand it. Here is what I have so far, where TIMSK0 is a register and TO1E0 is the least significant bit inside TIMSK0

TIMSK0 &= ~(1<<TO1E0)

So I've been thinking about this logically and trying to understand rather than memorize. The above example in full notation would be:

TIMSK0 = TIMSK0 & ~(1<<TO1E0)

Assuming TIMSK0 is currently 0000 0001 then that means TO1E0 = 1 then the argument looks like ~(1<<1) which implies shift 1 left by 1, which results in 0. But then not of 0 is 1 so then I am ANDing the register TIMSK0 with 1

0000 0001 & 1

which also results in the same value 0000 0001, I am very sure I messed up somewhere in my logic.

phuclv
  • 37,963
  • 15
  • 156
  • 475
  • Why is `TO1E0` 1 in that example? If it's supposed to be the position of the lsb, shouldn't it be 0? If it's supposed to be a mask instead of an index then shifting left by it would make no sense – harold Jul 31 '18 at 18:27
  • I guess I am missing something, but isn't (1<<1)=0000 0010, and Not 0000 0010 = 1111 1101 (assuming 8-bit registers)? Can you give us a link to where you got the code from? – Andrew Morton Jul 31 '18 at 18:35
  • TO1E0 is 1 arbitrarily, I was trying to run through both scenarios where it could be 0 or 1, when it is 0, it works, but when it is 1, the bit is still enabled thus confusing me. I'm not sure how these registers are "cleared" and it must be do to a confusion in my understanding. video for reference https://youtu.be/648Tx5N9Zoc?t=423 – user1174774 Jul 31 '18 at 18:50
  • lastly, if you go here: https://playground.arduino.cc/Code/BitMath x &= ~(1 << n); // forces nth bit of x to be 0. all other bits left alone it also says that this notation forces bits to be 0. But I don't really understand why – user1174774 Jul 31 '18 at 18:51
  • When `TO1E0 = 1` the expression still works, but since `TIMSK0 = 1` its bit 1 is already not set so resetting it has no effect. Anyway I still don't understand what you want to know – harold Jul 31 '18 at 19:07
  • I guess I would like to see the operations in full, I'm not really following how bits are cleared with that statement – user1174774 Jul 31 '18 at 20:32
  • `which implies shift 1 left by 1, which results in 0?` is incorrect. `1 << 1` results in 2 – phuclv Aug 11 '18 at 02:29

2 Answers2

0

Let's talk about expression

x &= ~(1 << n)

How does it work? Let's say n = 4, x = 19. Then here is what happens:

(1 << n)
0000 0001 //is a binary representation of 1
(1 << 4) = 0001 0000 = 16//shifted by n=4 bits

~(1 << n)
~(0001 0000) = 1110 1111 //as ~ inverts every bit

x &= ~(1 << n)
0001 0011 //is a binary representation of 19
0001 0011 & 1110 1111 = 0000 0011 = 3 //as & is implemented bit by bit

So result is 0000 0011 with cleared 4th bit compared to source 0001 0011

This uses more simple rule that (talking about bits now) x & 1 = x, x & 0 = 0

Alex Yokisama
  • 1,021
  • 7
  • 8
0

You're incorrect at this step

~(1<<1) which implies shift 1 left by 1, which results in 0?

1 << 1 results in 2. So basically TIMSK0 &= ~(1<<TO1E0) will clear the bit number TO1E0

  • When TO1E0 = 0, 1 << TO1E0 = 1 and ~(1 << TO1E0) = ~1 = 0b111...1110, therefore the expression will clear the least significant bit
  • When TO1E0 = 1, 1 << TO1E0 = 2 and ~(1 << TO1E0) = ~2 = 0b111...1101, therefore the expression will clear the second significant bit

As a result when TIMSK0 = 0000 0001 and TO1E0 = 1 then TIMSK0 won't be changed after the statement, since it's second significant bit is already zero

See How do you set, clear, and toggle a single bit?

phuclv
  • 37,963
  • 15
  • 156
  • 475