C語言位運算遇到的坑
阿新 • • 發佈:2018-02-13
右移 ble 實現 ret ade int 只需要 res 置0
在Data Lab中有一個logicalShift函數給定一個值x和需要移動的位數n,要求只是用運算符:~ & ^ | + << >>,實現邏輯右移運算。思考了很久,然後我寫出了如下的代碼:
/* * logicalShift - shift x to the right by n, using a logical shift * Can assume that 0 <= n <= 31 * Examples: logicalShift(0x87654321,4) = 0x08765432 Legal ops: ! & ^ | + << >> * Max ops: 20 * Rating: 3 */ int logicalShift(int x, int n) { return ( x >> n ) & ~( ( ( x & 0x80000000) >> n ) << 0x1) ); }
我的思路是:
- 如果x是負值,x >> n會讓所有位右移n位,前n位補1,而在邏輯右移中前n位補0。解決這個問題,只需要把除去最高位的其他位置0,然後右移n位,再左移1位,再把這個數取反,和原來右移n位的值按位and,即可得到正確的結果。
- 如果x是正值,因為x & 0x80000000得到的結果為0,因此~( ( ( x & 0x80000000) >> n ) << 0x1) )為全1,不影響左邊的計算結果。事實上對於正值,邏輯右移和邏輯左移是相同的。
比如:
x | n | x >> n | x & 0x80000000 | x & 0x80000000) >> n | ( ( x & 0x80000000) >> n ) << 0x1) | ~( ( ( x & 0x80000000) >> n ) << 0x1) ) | Result |
---|---|---|---|---|---|---|---|
0x80000000 | 2 | 0xe0000000 | 0x80000000 | 0xe0000000 | 0xc0000000 | 0x3fffffff | 0x20000000 |
C語言位運算遇到的坑