1. 程式人生 > 其它 >07. C Pro 關於正碼/反碼/補碼

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;
}