#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.
CodePudding user response:
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:
- if
nbits
is a multiple ofBITS_PER_LONG
, anunsigned long
with all bits set, - otherwise, an
unsigned long
with the lownbits%BITS_PER_LONG
bits set.