不使庫函式(abs)通過位運算實現取一個整數的絕對值
阿新 • • 發佈:2021-02-12
不使庫函式(abs)通過位運算實現取一個整數的絕對值
問題出自:2017年韓山師範學院本科插班生考試 第3題
需要用到的知識點
- 原碼、補碼、反碼
- 負數轉2進位制
- 位運算
- 2進位制乘法(關係不大)
解題程式碼:
-
int myabs(int n) { return n * ((n>>31<<1) +1); }
-
整型變數 n 右移31位 左移1位 +1 乘 n
原碼
- 正數的原碼就是它本身,符號位 為 0
- 負數符號位為1,八位二進位制舉例:1000 1010 = (-10)10
反碼
- 正數的反碼和原碼相同
- 負數的反碼符號位置不變,其他按位取反,整數-10的反碼是:1111 0101
補碼
- 正數的補碼和原碼一樣
- 負數的補碼為反碼+1 整數-10的補碼是:1111 0110 這就是整數-10在計算機中的儲存形式
負數轉二進位制
- 計算機中沒有直接做減法,是通過加法來實現的,所以負數在計算機中是由原碼的補碼+1得到的
- 符號位為1,符號為不變
- 原碼轉補碼:取反+1
- 補碼轉原始碼:-1取反
位移運算
左移運算<<
- 低位補零,高位溢位
- 不溢位的情況下相當於乘2
右移運算>>
- 邏輯右移&&算數右移
- 對無符號數,右移時高位補零,低位溢位
- 對於有符號數,原來是0,同上,原來是1(即負數),左邊移入0還是1,取決於計算機系統,有系統補0有系統補1,補 0 的稱為邏輯右移,補 1 的稱為算數右移
- 舉例 >>1
- 1011 0011
- 0101 1001(邏輯右移)
- 1101 1001(算數右移)
- Visual C++和其他C編譯器採用算數右移,有符號數右移時,原符號位為1,左邊高位補1
二進位制乘法
-
舉例:
解題
-
//以-2為 n 舉例 //n * ((n>>31<<1)+1) //-2*(-2>>31<<1)+1 1000000000 0000000000 0000000000 10 //-2的原碼 1111111111 1111111111 1111111111 01 //-2的反碼 1111111111 1111111111 1111111111 10 //-2的補碼 -2反碼+1 //這是-2 在計算機中的表示 以原始碼的補碼錶示