C++官方参考链接:Numerical Bases - C++ Tutorials (cplusplus.com)
数值基数
从孩提时代起,我们就开始用十进制来表示数量。这个命名法在我们看来很符合逻辑,但在古罗马人看来却并非如此。对他们来说,每一个用来表示数字的符号都代表着相同的值:
I 1 II 2 III 3 IV 4 V 5
所有的I符号总是表示值1(one),而V符号总是表示值5(five)。然而,这在我们的十进制系统中是不会发生的。当我们写十进制符号1时,我们并不总是在讨论1的值(罗马数字中的I)。例如:
1 I 10 X 100 C
在这些情况下,符号1并不总是值1(或罗马数字中的I)的值。例如,在第二种情况下,符号1表示10(或罗马中的X)的值,而在第三种情况下,符号1表示100(或C)的值。
例如:
275并不等于2+7+5,而是可以分解为200+70+5:
200 + 70 5 --- 275
因此,第一个“2”符号相当于200(2*100),第二个“7”符号相当于70(7*10),而最后一个符号对应的值是5(5*1)。
这是因为我们的系统是一个位置数字系统。因此,给定数字的值取决于它在被表示的整个数字中的位置。所有这些都可以用一种非常简单的方式用数学表示出来。例如,为了表示数值182736,我们可以假设每一位数字都是自身乘以10的指数幂,以每一位数字的位置为指数,从右开始是10^0,接着是10^1,10^2,以此类推:
八进制数(以8为基数)
就像我们的“普通”数字是以10为底数(或基数为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(在罗马语中是seventeen或XVII)在C++中被表示为八进制数字021。我们可以将之前看到的处理十进制数的相同机制应用到八进制数上,只需考虑它的基数是8。例如,取八进制数字071263:
因此八进制数字071263用十进制数字表示为29363。
十六进制数(以16为基数)
就像十进制数有10个不同的用来表示的数字(0123456789),八进制数有8个不同的数字(01234567),十六进制数有16个不同的数字,由数字0到9和字母A、B、C、D、E和F表示,它们一起为我们表示十六进制数所需的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 (0,x)。
同样,我们可以使用相同的方法将一个数从一个基数转换为另一个基数:
二进制表示
八进制数和十六进制数在比特世界中比十进制数有相当大的优势,它们的基数(8和16)是2(分别为2^3和2^4)的完全倍数,这使得我们可以比十进制数(基数为2x5)更容易地从这些基数转换为二进制数。例如,假设我们想要将下面的二进制序列转换为其他基数的数:
110011111010010100
为了将其转换为十进制数,我们需要执行与之前从十六进制数或八进制数转换类似的数学操作,这将得到十进制数212628。
然而,将这个数列转换为八进制数只需要几秒钟的时间,即使数学不太熟练的人也可以通过看到它来完成:由于8=2^3,我们将把二进制值分成3个数字一组:
110 011 111 010 010 100
现在我们只需要将每一组分别转换成八进制基数:
110 011 111 010 010 100 6 3 7 2 2 4
结果是637224。同样的过程可以反向执行,从八进制转换为二进制。
为了对十六进制数进行操作,我们只需要执行相同的过程,但将二进制值按4个数字分组,因为16=2^4:
11 0011 1110 1001 0100 3 3 E 9 4
因此,二进制表达式110011111010010100可以在C++中表示为212628(十进制)、0637224(八进制)或0x33e94(十六进制)。
十六进制编码在计算机科学中特别有趣,因为现在计算机是基于由8个二进制位组成的字节,因此每个字节都匹配2个十六进制数所能表示的范围。由于这个原因,它经常被用来表示转换为二进制的值或由二进制转换而来的值。