07. C Pro 關於正碼/反碼/補碼
一、正負數的表示:
計算機只能儲存01,正負數的儲存有別!以最高位作為符號位:0=正數,1=負數!
正數的原碼==反碼==補碼:
EG:10 =》 0000 1010
負數的原碼,即將其正數表示的符號位,改為1:
EG:-10 =》 1000 1010
負數的反碼,即其原碼的符號位不變,其他位取反:
EG:-10 =》 1111 0101
負數的補碼,即反碼 + bit(1):
EG:-10 =》1111 0101 + 0000 0001 = 1111 0110
二、任何資料都是以其二進位制的補碼形式儲存在記憶體中的:因為計算機中只有加法沒有減法,補碼儲存的資料其計算效率最高
下面我們看一個例子 這個例子也是我看的時候特別能幫助我理解的 清晰明瞭,例如 :
3 - 2; 這個減法運算對於計算機而言它的理解是 3 + (-2) = 1
使用原碼計算:
3的原碼 00000000 00000000 00000000 00000011
-2的原碼 10000000 00000000 00000000 00000010
----------------------------------------------------
10000000 00000000 00000000 00000101 =》結果是1個負數明顯是不對的
使用反碼計算:
3 的反碼: 00000000 00000000 00000000 00000011
-2的反碼: 11111111 11111111 11111111 11111101
--------------------------------------------------
00000000 00000000 00000000 00000000 =》0
使用補碼計算:
3 的補碼: 00000000 00000000 00000000 00000011
-2的補碼: 11111111 11111111 11111111 11111110
-------------------------------------------------
00000000 00000000 00000000 00000001 =》1
三、列印負數的補碼,摘自:https://blog.csdn.net/wyt734933289/article/details/72889835
一個數的右移==算術右移,數學上表示除以2:如果是有符號數,對列印其 bit 不利,應先轉為無符號數!
void main() {
int num[20], cnt = 0;
short a = -10;
unsigned short b = a;
while (b) {
num[cnt++] = b & 1; // 從最右邊開始取位
b >>= 1; // 右移一位 == %2 =》左移== *2
}
for (int i = cnt - 1; i >= 0; i--)
printf("%d ", num[i]); // 倒敘輸出
}
四、位運算
1.(int a) & 0x[0 | FF | xx] :將指定位清零,或者獲取指定位!
2.(int a) | 0x[0 | FF | xx] :設定指定位=0|1;
3.(int a) ^ 0x[0 | FF | xx] :定位翻轉,或者數值交換!
EG:要獲取一個無符號數中從第 p 位開始的 n 位二進位制資料(資料右端對齊)
unsigned int getbits(unsigned int x, unsigned int p, unsigned int n) {
unsigned int a, b;
a = x >> (p + 1); // a 右移 p+1 位(位計數從0開始)
b = ~(~0 << n); // ~0=全1,左移 n 位,再取反 == 右側 n 位 1
return a & b;
}