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
859 views
in Technique[技术] by (71.8m points)

c - Create a mask that marks the most significant set bit, using only bitwise operators

This was part of a larger programming assignment that was due for me last night. Couldn't figure out this problem, but I'm curious as to how it could be solved.

The function int greatestBitPos(int x) should return an int mask that marks the position of the most significant bit. If x==0, return 0. No control structures (if, while, ?:) allowed.

Example: greatestBitPos(96) = 0x40

Legal operators: ! ~ & ^ | + << >> =

This website on bit twiddling is something I used as a starting point, especially the second algorithm. However, it uses < comparisons, something this problem doesn't allow.

All ideas are welcome, thanks!

Edit: Please assume 2's complement, 32-bit integers. For all negative numbers, they have their topmost bit set, so the return value should be 0x80000000.

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

Updated to work for negative numbers (assuming that this should return 0x80000000 since these numbers have their top bit set )

int gbp(int n) {
 // return log(2) of n
 unsigned int m;
 m = n;
 m = m | m >> 1;
 m = m | m >> 2;
 m = m | m >> 4;
 m = m | m >> 8;
 m = m | m >> 16;
 m = m & ((~m >> 1)^0x80000000);
printf("m is now %d
", m);
return m;
}

Explanation:

Starting with any bit pattern, when we shift right by 1 and take the OR, adjacent bits will become 1. Example

00010100
00001010
--------
00011110

You repeat this until you have all ones to the right of the leading digit, by successively shifting 2, 4, 8, 16 (if you have 32 bit numbers; for larger int you keep going).

Finally you need to "strip all the other ones" by inverting the number, right shifting by 1, and taking the AND:

00011111 AND 11110000 = 00010000

and there you have it.

For negative numbers, the final manipulation ensures that you don't kill the top bit if it exists. If you wanted something else to be done with negative numbers, let me know what it is.


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

...