The trick here is that it leaves the low-order 7 bits of n unchanged. If you were storing flags in n, for example, you might want to clear only a few of them and leave the others untouched.
The bitwise AND operator & is often used to mask off some set of bits, for example
n = n & 0177;
sets to zero all but the low-order 7 bits of n.
I don't understand why this expression has that effect. Wouldn't n = 0; have the same effect? Or maybe n = ~0177;?
x could be anything before this operation. The idea is that the bits of x have some values (perhaps you know what they are, perhaps you don't) and that you want to set the lowest six bits to be zero without changing the other bits.
x = x & ~077
sets the last six bits of x to zero. Note that x & ~077 is independent of word length, and is
thus preferable to, for example, x & 0177700, which assumes that x is a 16-bit quantity.
What does x look like before the operation is performed. 16 0-bits or is it in some state I don't know about? And why is word length coming into this discussion out of nowhere?
The word length discussion is because if you calculated the value ~077 for 16-bit integers, you'd get 0177700 -- but that only works if you're using 16-bit integers. Using the expression ~077 will work for 8-bit, 16-bit, 32-bit, or whatever-bit integers, so it's better to use it.
I'll use eight-bit variables in my examples here.
As an illustration of some of the bit operators, consider the function getbits(x,p,n) that returns the (right adjusted) n-bit field of x that begins at position p. We assume that bit position 0 is at the right end and that n and p are sensible positive values. For example, getbits(x,4,3) returns the three bits in positions 4, 3 and 2, right-adjusted.
/* getbits: get n bits from position p */
unsigned getbits(unsigned x, int p, int n)
return (x >> (p+1-n)) & ~(~0 << n);
The expression x >> (p+1-n) moves the desired field to the right end of the word. ~0 is all 1-bits; shifting it left n positions with ~0<<n places zeros in the rightmost n bits; complementing that with ~ makes a mask with ones in the rightmost n bits.
My brain collapsed.
Given a number like 0011 1011, and asked for a "window" starting from 4 of width 3 (i.e., the call getbits(0x3b, 4, 3)) is supposed to do this:
Anyway, not sure if that's a very good explanation, but read it carefully and see if you get it. Hopefully I understood what getbits was supposed to do.
bit 7654 3210
so starting at bit 4 is starting here
a width of 3 will be the following bits
so if we want to get these bits, here's one way (the way the function uses).
Shift the number left by (4+1-3), i.e. 2, to obtain
>> 2 becomes
Now if we want the leftmost three bits, we want to AND with a mask of 000 0111.
We generate this mask with the following operations:
start with ~0 (all 1's):
left shift by 3: (shifting in zeros)
now invert the bits again:
This is the mask we wanted. AND'ing our (right-shifted) number with this mask gives
& 0000 0111
which is what we wanted.