數制基礎

從小時候起,我們就都使用十進位制來表示數量。這種對我們來說似乎很合乎邏輯的命名法,對於古羅馬的居民來說可能並非如此。對他們而言,他們用來表示數字的每個符號總是代表相同的值。

I      1
II 2
III 3
IV 4
V 5

所有的I符號無論放在哪裡,都總是代表值 1(一),而V符號總是代表值 5(五)。然而,在我們的十進位制系統中情況並非如此。當我們寫下十進位制符號 1 時,我們並不總是指值為一(羅馬數字中的 I)。例如:

  1    I
10 X
100 C

在這些情況下,我們的符號 1 並不總是具有值為一(或羅馬數字中的 I)的含義。例如,在第二種情況下,符號 1 代表值為十(或羅馬數字中的 X),而在第三種情況下,1 代表值為一百(或 C)。

例如:

275並不等同於 2+7+5,它更應該被分解為 200+70+5。

 200
+ 70
5
---
275

因此,第一個“2”符號等同於 200 (2 x 100),第二個“7”符號等同於 70 (7 x 10),而最後一個符號對應於值 5 (5 x 1)。

這是因為我們的系統是位值記數法。因此,一個給定數字的值取決於它在整個被表示的數字中的位置。以上所有內容都可以用一種非常簡單的方式進行數學表示。例如,要表示值 182736,我們可以假設每個數字都是它自身乘以 10 的冪,冪次由其位置決定,從右邊開始是 100,接著是 101、102,依此類推。


八進位制數(基數為 8)

就像我們的“普通”數字是以 10 為基數(或稱十進位制)一樣,因為我們有 10 個不同的數字(從 0 到 9),

0123456789

八進位制數只包括從 0 到 7 的值的表示,

01234567

因此,它的數學基數是 8。在 C++ 中,八進位制數總是以一個0數字開頭來表示。讓我們看看如何用八進位制書寫最初的幾個數字:

octal  decimal
----- -------
0 0 (zero)
01 1 (one)
02 2 (two)
03 3 (three)
04 4 (four)
05 5 (five)
06 6 (six)
07 7 (seven)
010 8 (eight)
011 9 (nine)
012 10 (ten)
013 11 (eleven)
014 12 (twelve)
015 13 (thirteen)
016 14 (fourteen)
017 15 (fifteen)
020 16 (sixteen)
021 17 (seventeen)

因此,例如,數字 17(十七,或羅馬數字中的 XVII)表示為021在 C++ 中作為一個八進位制數。我們可以將我們之前看到的十進位制數的機制應用到八進位制數上,只需考慮其基數是 8。例如,取八進位制數071263:


因此,八進位制數071263用十進位制數表示為 29363。

十六進位制數(基數為 16)

就像十進位制數有 10 個不同的數字來表示(0123456789),八進位制數有 8 個(01234567),十六進位制數有 16 個不同的數字,它們由數字 0 到 9 和字母 A、B、C、D、E、F 表示,這些共同構成了我們表示以 16 為基數的數字所需的 16 個不同符號。

hexadecimal  decimal
----------- -------
0 0 (zero)
0x1 1 (one)
0x2 2 (two)
0x3 3 (three)
0x4 4 (four)
0x5 5 (five)
0x6 6 (six)
0x7 7 (seven)
0x8 8 (eight)
0x9 9 (nine)
0xA 10 (ten)
0xB 11 (eleven)
0xC 12 (twelve)
0xD 13 (thirteen)
0xE 14 (fourteen)
0xF 15 (fifteen)
0x10 16 (sixteen)
0x11 17 (seventeen)

在 C++ 中,十六進位制數的字首是0x(零,x)。

我們再次可以使用相同的方法將一個數字從一個基數轉換到另一個基數。


二進位制表示

在位元的世界裡,八進位制和十六進位制數相對於我們的十進位制數有一個相當大的優勢,那就是它們的基數(8 和 16)是 2 的完美倍數(分別為 23 和 24),這使得我們可以比從十進位制數(其基數為 2x5)更容易地將這些基數轉換為二進位制。例如,假設我們想將以下二進位制序列轉換為其他基數的數字:

110011111010010100

為了將其轉換為十進位制,我們需要進行類似於我們之前用來從十六進位制或八進位制轉換的數學運算,這將得到十進位制數 212628。

然而,要將這個序列轉換為八進位制,我們只需要幾秒鐘,即使是數學最差的人也能一眼看出來:由於 8 是 23,我們將二進位制值分成 3 個數字一組:

110 011 111 010 010 100

現在我們只需將每組分別轉換為八進位制數基數:

110 011 111 010 010 100
6 3 7 2 2 4

得到的結果是數字 637224。這個過程同樣可以反向進行,從八進位制轉換到二進位制。
為了用十六進位制數進行運算,我們只需執行相同的過程,但是將二進位制值分成 4 個數字一組,因為 16 = 24

11 0011 1110 1001 0100
3 3 E 9 4

因此,二進位制表示式 110011111010010100 在 C++ 中可以表示為 212628(十進位制)、0637224(八進位制)或 0x33e94(十六進位制)。

十六進位制程式碼在計算機科學中特別有意義,因為當今的計算機基於由 8 個二進位制位組成的位元組,因此每個位元組正好對應 2 個十六進位制數可以表示的範圍。因此,它非常頻繁地用於表示與二進位制基數相互轉換的值。