Reputation: 79
#define BITMAP_LAST_WORD_MASK(nbits) (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
This is the operation of bitmap in Linux. nbits
is 3 and BITS_PER_LONG
is 64. I thought the expression should be ~0UL >> -3
and the result means I have three items. In the expression I do the &
first and add -
. Maybe the expression has been wrong already.
Upvotes: 0
Views: 234
Reputation: 222846
Assuming nbits
is nonnegative, -(nbits) & (BITS_PER_LONG - 1)
computes BITS_PER_LONG - nbits%BITS_PER_LONG
except that, if nbits
is a multiple of BITS_PER_LONG
, it produces zero instead of BITS_PER_LONG
.
~
inverts all the bits in its operand, so ~0UL
is a long
with all its bits set. Shifting this right by BITS_PER_LONG - nbits%BITS_PER_LONG
shifts zeros into the high bits, leaving only the low nbits
set to one. Since the expression shifts by the &
expression rather than BITS_PER_LONG - nbits%BITS_PER_LONG
, if nbits
is zero, it does not shift at all, leaving all bits set.
Thus the result of (~0UL >> (-(nbits) & (BITS_PER_LONG - 1)))
is:
nbits
is a multiple of BITS_PER_LONG
, an unsigned long
with all bits set,unsigned long
with the low nbits%BITS_PER_LONG
bits set.Upvotes: 2