計算機中的二進制運算


一、計算機中的二進制位運算

  二進制的位運算並不是很難掌握,因為位運算總共只有5種運算:與、或、異或、左移、右移。與、或和異或運算的規律我們可以用表1總結如下。

表1 與、或、異或的運算規律
與(&) 0 & 0 = 0 1 & 0 = 0 0 & 1 = 0 1 & 1 = 1
或(|) 0 | 0 = 0 1 | 0 = 1 0 | 1 = 1 1 | 1 = 1
異或(^) 0 ^ 0 = 0 1 ^ 0 = 1 0 ^ 1 = 1 1 ^ 1 = 0

  左移運算符m<<n表示把m左移n位。在左移n位的時候,最左邊的n位將被丟棄,同時在最右邊補上n個0。比如:

  • 00001010 << 2 = 00101000
  • 10001010 << 3 = 01010000

  右移運算符m>>n表示把m右移n位。在右移n位的時候,最右邊的n位將被丟棄。但右移時處理最左邊的情形要稍微復雜些。如果數字是一個無符號數值,則用0填補最左邊的n位;如果數字是一個有符號數值,則用數字的符號位填補最左邊的n位。也就是說,如果數字是正數,則右移之后在最左邊補n個0;如果數字是負數,則右移之后在最左邊補n個1。下面是對8位有符號數進行右移的例子:

  • 00001010 >> 2 = 00000010
  • 10001010 >> 3 = 11110001

二、unsigned與signed的區別

  首先回顧一下二進制的正負數表達方式。在計算機中使用補碼表示正負數,其中正數的補碼等於其本身,負數的補碼則為原碼取反再加1。用4位二進制表示-1 ~ 7如表2所示。

表2 4位二進制
補碼 十進制數值
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1

  由表2可知,在32位的系統中,int型的-1在計算機中的存儲的補碼為0xFFFF FFFF

  如同int a;一樣,int 也能被其它的修飾符修飾。除void類型外,基本數據類型之前都可以加各種類型修飾符,類型修飾符有如下四種:

  1. signed----有符號,可修飾char、int(Int是默認有符號的)
  2. unsigned-----無符號,修飾int 、char
  3. long------長型,修飾int 、double
  4. short------短型,修飾int

2.1 無符號整型(unsigned int)

(1)我們都知道整型是4個字節(有些編譯器不同,可能會是2個),即32位,無符號整型當然也為32位。
(2)既然是32位,無符號整型的取值是32個032個1,即:**04294967295**
(3) 我們舉個例子:32位有點長,所以我們拿16位的unsigned short int 來舉例。

  short int 是16位的,無符號的范圍是0~65535。就拿十進制的32767來說,它的二進制為:0111 1111 1111 1111

  對於無符號的整型32767來說,它的二進制的最高位稱為數據位,即那個0就是數據位,數據位是要參與運算的,如果我們把0改成1,即16個1,它的十進制就是65535(就是2的15次方+2的14次方...一直加到2的0次方),這是不同於有符號整型的。

(4) 為了進行理解(3)中的含義,做一個程序說明:

#include <stdio.h>
main()
{
    unsigned short int a=32767, b=a+1;//定義短整型無符號
    printf("a=%u\nb=%u\n",a,b);//以無符號輸出
}

  定義的時候a=32767,也就是0111 1111 1111 1111,輸出的依然是32767,a+1=32768, 二進制為1000 0000 0000 0000,輸入依然為32768。根據(3)中講解的,無符號整型的二進制最高位為數據位,數據位為0為1都是按照正常來算的。

2.1 有符號整型(signed int)

(1)有符號整型也是32位;

(2)它的取值范圍就與無符號整型不同了。它的范圍是-2147483648~2147483647這個范圍可以理解為無符號整型的一半變成了負數;

(3) 我們舉個例子:32位有點長,所以我們拿16位的unsigned short int 來舉例。

  short int 是16位的,有符號的范圍是-32768~32767。這個時候可能就有人發問了,32768用二進制表示為1000 0000 0000 0000,那么這個負的32768的負號又怎么理解呢?看下面。

  還是以32767為例子,它的二進制為:0111 1111 1111 1111。對於有符號整型32767來說,它的二進制最高位稱為符號位(而不是數據位了),符號位顧名思義就是決定正負號的,規則:0是正,1為負。

(4) 為了進行理解(3)中的含義,做一個程序說明:

#include <stdio.h>
main()
{
	// 定義有符號類型
    short int a=32767, b, c, d;
    b=a+1;
    c=a+2;
    d=a+3;
    printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d);
}

(5)了解了什么是補碼后再來看上述程序:32767的二進制為:0111 1111 1111 1111。我們來計算一下c的值為什么會等於-32767。c=32767+2,c的二進制為:1000 0000 0000 0001(32767的二進制加2),c的這個二進制是在計算機中存儲的補碼,需要將它轉換為原碼,也就是將c的二進制數減一再取反。得到的二進制原碼為:1111 1111 1111 1111。我們已經說過,符號位為1,表示負值,並不參加運算,所以此二進制的十進制為:-32767

(6)通過程序也可以發現一個規律,short int的取值范圍是-32768~32767,把頭尾連接起來形成一個環就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM