Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
598 views
in Technique[技术] by (71.8m points)

bit manipulation - What is the best practice way to create a bitmask for a range of bits?

I can think of three ways to do this off the top of my head. I'll outline them real quick.

char mask = (1<<top)
mask = mask-1
mask = mask>>bot
mask = mask<<bot
3 shifts, 1 addition

char topMask = (1<<top)
topMask = topMask -1
char botMask = (1<<bot)
botMask = botMask - 1
char mask = topMask - botMask
2 shifts, 3 additions

char mask = (1<<(top-bot))
mask = mask - 1
mask = mask << bot
2 shifts, 2 additions

It seems like the first one would be a little faster? Is one considered best for style reasons? Is there a really good way I'm missing, or am I doing something stupid? Thanks!

I'd especially be interested if anyone could point me to a place this is done in the linux kernel.

EDIT: someone posted something like this as another way and deleted it? Pretty similar to the second one. But XOR instead of subtract.

char mask = ((1<<top)-1)^((1<<bot)-1)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could try a lookup table approach:

static const char LUT[][] = { // index like this LUT[bot][top]
//top:    0     1     2     3     4     5     6     7     8
       0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, // bot: 0
       0x00, 0x00, 0x02, 0x06, 0x0E, 0x1E, 0x3E, 0x7E, 0xFE, // bot: 1
       0x00, 0x00, 0x00, 0x04, 0x0C, 0x1C, 0x3C, 0x7C, 0xFC, // bot: 2
       0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0xF8, // bot: 3
       0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x70, 0xF0, // bot: 4
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x60, 0xE0, // bot: 5
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xC0, // bot: 6
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // bot: 7
       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // bot: 8
};

char mask = LUT[bot][top];

Also: If for whatever reason you go with bit manipulation this solution requires less ops. In addition a superscalar processor should evaluate the left and right side of the xor in parallel.

char mask = (0xFF << top) ^ (0xFF << bot);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...