In an Array of bytes , each of them occupies a memory location.
Each byte has 8 bits . That is, at each position of the array we have eight bits, so we have to have a way to get each one individually.
To facilitate, let's visualize each bit at your address:
byte 10100111 10010001 01101111 01111111 ....
^- usaremos o bit 19 como exemplo
endereço de memória n n+1 n+2 n+3 ...
posição do bit: 7......0 15.....8 23....16 31....24 ...
(bit menos significante para a direita)
Notice that every 8 bit positions, we advance 1 memory location. So, to know the position of the bit in memory, we need to divide the position of the bit by 8. Here's part of the code:
return 1 & (array[index / 8] >> (index % 8));
^^^^^^^^^
Ok, in our example, bit 19 is in 19/8, which gives 2 (in integers). We already know that we have to read the address n+2
, which has this value:
0b01101111
Well, our index
is 19. We've already used 19 to get n+2
, dividing by 8, but we have to know where the right bit is. For this we get 19 % 8
, which is this part of the code:
return 1 & (array[index / 8] >> (index % 8));
^^^^^^^^^
If the code were mine, I'd probably use index & 7
, for the sake of taste, but in the end it's the same. In this case, the value returned is 3
So, our "calculation" looks like this:
return 1 & ( 0b01101111 >> 3 )
^
The operator >>
moves the byte 3x to the right, after all, who has implemented the option by counting from right to left:
return 1 & ( 0b00001101 )
^
Finally the 1 &
will discard the rest of the byte and return only our bit 19, which in this case is 1
.
When you do the inverse, which is to set or reset the bit , you will just use the opposite operator, <<
, to set the bit in its position right, something like this (you can optimize it, and there may be some silly error, just an example):
array[index / 8] = array[index / 8] & ~(1 << (index % 8)) | (bit & 1) << (index % 8);
What if the person had opted for the most significant right?
11100101 10001001 11110110 11111110 ...
0......7 8.....15 16....31
^
Simple, the formula would look something like this:
return 127 & ( array[index / 8] << (index % 8) ) / 127;
And this would happen:
return 127 & ( 0b11110110 << 3 ) / 127;
^
Reducing this:
return 127 & ( 0b10110000 ) / 127
^
What would give 1
the same way.
If you want more details of the >>
operator, here is a brief explanation:
What are operators for | & < < > >?