跳轉到

整數

在電腦的世界中,我們使用0和1來儲存資料,我們把此稱為1個bit,有了一連串的bit,我們就可以二進位來儲存一個數字。

而電腦中的基本單位為 8bits ,我們稱其為1個byte

了解到了這些基本知識,讓我們看看整數是如何存的。

正整數

正如前面所說,我們把一個數字從十進位轉成二進位後,就可以放進固定大小的記憶體存了,下面為具體過程。

溢位

假如今天要存的數放進固定大小的記憶體太大了,存不下怎辦?

丟掉不管就好了阿!

變數的值如果超過記憶體能存的上限,則稱為溢位,溢位在數值運算上是一個精妙的設計,在等等的範例會在說明。

負數

經過前面的影片範例,想必你對正整數的儲存有一定的概念,那如果今天要存的是負數,要怎樣做?

在談及怎樣做之前,我們先談一下補數的概念。

一補數

在電腦當中,我們讓最左邊的bit代表著正負。如果是0代表此數為正,如果為負則其餘bit 0 -> 1 、 1 -> 0,例如:

\[121_{10} = 01111110_{2}\]
\[-121_{10} = 100000001_{2}\]

二補數

二補數的特性與一補數相近,唯一的區別是當他是負數時,需要在轉成一補數後+1,例如:

\[121_{10} = 01111110_{2''}\]
\[-121_{10} = 10000010_{2''}\]
\[(假設我們只有1byte=8bits來存資料)\]

接下來你應該會有一個疑問,為何我們需要二補數?這不是多一個步驟嗎? 讓我們試著把 121 和 -121 的二補數相加,並導入溢位的概念:

\[ 01111110_{2''} + 10000010_{2''} = _{1}00000000_{2''}\]

最左邊的1發生溢位,會消失(故使其字體縮小),結果為正確答案,神奇對吧!

事實上,電腦中我們只有設計加法器,並沒有設計減法器,就是因為我們可以透過二補數+溢位這兩個巧妙的設計, 來達成整數的快速運算。

C++中的整數型態

在了解到這些背後知識後,我們來討論C++所有的整數型態。 由於每個變數所需要的範圍不同,C++特別設計了好幾種的型態,來讓你使用。

而每個型態的範圍,簡化過後大致上可以分成下面幾個狀況(詳細請參考reference的連結1):

type 32 bits compiler 64 bits compiler
unsigned char \(-2^7\sim2^7-1\) \(-2^7\sim2^7-1\)
unsigned short \(-2^{15}\sim2^{15}-1\) \(-2^{15}\sim2^{15}-1\)
unsigned int \(-2^{31}\sim2^{31}-1\) \(-2^{31}\sim2^{31}-1\)
unsigned long \(-2^{31}\sim2^{31}-1\) \(-2^{63}\sim2^{63}-1\)
unsigned long long \(-2^{63}\sim2^{63}-1\) \(-2^{63}\sim2^{63}-1\)

一般而言,在使用整數型態,我們會宣告int做使用。 那C++同時也提供沒有負數的型態,只要在這些型態前面加上unsigned即可。

type 32 bits compiler 64 bits compiler
char \(0\sim2^8-1\) \(0\sim2^{8}-1\)
short \(0\sim2^{16}-1\) \(0\sim2^{16}-1\)
int \(0\sim2^{32}-1\) \(0\sim2^{32}-1\)
long \(0\sim2^{32}-1\) \({0}\sim2^{64}-1\)
long long \({0}\sim2^{64}-1\) \({0}\sim2^{64}-1\)

這邊有個點要注意一下,在某些特殊情況下,你的編譯器可能會是32位元的,long的大小會比較小,所以在宣告8byte(64bits)大小的整數型態時,請盡量使用long long,以避免出錯。

* 請注意,char同時為字元型態,詳細會在後面說明。

整數型態的相關運算

C++ 提供了基本的四則運算。

+ 代表加號。

-代表減法運算。

*代表乘法運算。

/代表除法運算。 請注意,整數的除法不會有小數點。

%代表取餘數。

請試著執行下方範例程式,並嘗試去理解它。

#include <iostream>

using namespace std;

int main(){
    int a = 126, b = -126;
    int ans1 = a + b;
    int ans2 = a - b ;
    int ans3 = a * b * a * b * a * b ;
    int ans4 = a / b;
    int ans5 = (a*b)%2;

    cout << ans1 << " " << ans2 << " "  << ans3 << " "  << ans4 << " "  << ans5 << endl;


    return 0;
}

reference
  1. https://en.cppreference.com/w/cpp/language/types