dwqs/blog

数制基础

dwqs opened this issue · 1 comments

dwqs commented

计算机的世界里只有二进制

二进制是一种数制。数制是"数据制度"的简称,是指数据的进位计数规则,表示数据逢几进位,又称"进位计数制"。如我们常用的十进制就是逢十进位,计算机中的二进制则是逢二进位。

在计算机系统中,我们常见的数制有四种:十进制、二进制、八进制和十六进制。当然,还有其它不常见的数制,如三进制、十二进制、二十进制以及六十进制等。不同的数制有不同的基数,在一种数制中所能使用的数码的个数称为该数值的基数。基数一般和数制类型对应,如二进制的基数为"2",八进制的基数为"8",十六进制的基数为"16"。每个进制都有一个最大数码和最小数码,前者通常是"基数"减1,后者通常是0。

由于有不同的数制,所以对于计算机程序中出现的任何一个"数"都需要专门的标志来进行区分。

数制区分

十进制(Decimal)

十进制是最常用的进制,基数是10,也就是说十进制有10个数字符号:0、1、2、3、4、5、6、7、8、9。十进制数的标志为 D,如(1250)D,也可用下标"10"来表示,如(1250)10

二进制(Binary)

如上文所说,计算机的世界里只有二进制。二进制是计算机运算时所采用的数制,基数是2,只有0和1两个数字符号。二进制的标志位 B,如(1001010)B,或者用下标"2"来表示,如(10011)2

八进制(Octal)

八进制的基数是8,其有8个数字符号:0、1、2、3、4、5、6、7。八进制的标志位 O 或者 Q,如(4563)O(大写的字母 O)、(4563)Q,或者用下标"8"来表示,如(4563)8。在 JavaScript 中,会把前缀为0(数值零)的数值解释为八进制,如123是十进制,0123则是八进制。

十六进制(Hexadecilma)

十六进制的基数是16,其有16个数字符号:0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。可以看到,16个数字符号除了十进制中的10个数外,还有6个英文字符(不区分大小写),这6个英文字符分别代表十进制中的10至15。十六进制数的标志位 H,如(4563)H,或者用下标"16"来表示,如(4563)16。在 JavaScript 中,会把前缀为0(数值零)和 x 的数值解释为十六进制,如123是十进制,0x123则是十六进制。

不同数制之间常见的对应关系

在一些场景之下,需要进行不同数制之间的转换,如二进制转十进制,或者十进制转二进制。下表列出了各数制的基础数字之间的对应关系:

二进制数 对应的十进制数 对应的八进制数 对应的十六进制数
0 0 0 0
1 1 1 1
10 2 2 2
11 3 3 3
100 4 4 4
101 5 5 5
110 6 6 6
111 7 7 7
1000 8 10 8
1001 9 11 9
1010 10 12 A
1011 11 13 B
1100 12 14 C
1101 13 15 D
1110 14 16 E
1111 15 17 F

不同数制之间的转换

同一个数,在不同的场景之下,可能需要不同的数制形式来表示。上文列举了常见的数在不同数制下的对应关系,而对于其它的数,则需要了解不同数制之间的转换规则了。

非十进制数转十进制数

非十进制数转十进制数采取的方法是"权值相加法",权值是指对应数值位的进制幂次方数。如二进制整数中的第0位(最低位,整数最右边的那位)的权值就是2的0次方,第1位的权值是2的1次方;同理,八进制整数中的第0位的权值是8的0次方,第1位的权值是8的1次方,依此类推。

权值相加法就是把非十进制数按位以对应的权值展开,然后相加即得出对应的十进制数。但是,在转换时要区分整数位和小数位。非十进制数的每位的权值会因是整数位还是小数位而不同:

  • 整数的第0位(最低位)的权值为对应进制的0次方,最高位(最左边的那位)的权值为对应进制的 n-1 次方
  • 小数的第一位(最高位,最靠近小数点的那位)的权值为对应进制的-1次方,最后一位(最低位,最右边的那位)的权值为对应进制的 -n 次方

整数转十进制数

二进制、八进制和十六进制的整数部分的一般表现形式为:bn-1bn-2...b1b0,按照权值相加法展开后的格式为:

bn-1 * kn-1 + bn-2 * kn-2...+ b1 * k1 + b0 * k0

其中 k 为对应的进制基数。

如二进制数(11010)2 的按权展开格式为:

1 * 24 + 1 * 23 + 0 * 22 + 1 * 21 + 0 * 20 = (26)10

如十六进制数(26345)16 的按权展开格式为:

2 * 164 + 6 * 163 + 3 * 162 + 4 * 161 + 5 * 160 = (156485)10

小数转十进制数

二进制、八进制和十六进制的小数部分的一般表现形式为:0.bn-1...b1b0,但幂次是反序排列的,和整数部分的幂次序列相反,且为负值,最高位幂次为"-1"。小数按照权值相加法展开后的格式为:

bn-1 * k-1 + bn-2 * k-2...+ b1 * k-(n-1) + b0 * k-n

其中 k 为对应的进制基数。

如二进制数(0.1011)2 的按权展开格式为:

1 * 2-1 + 0 * 2-2 + 1 * 2-3 + 1 * 2-4 = (0.6875)10

如八进制数(0.257)8 的按权展开格式为:

2 * 8-1 + 5 * 8-2 + 7 * 8-3 = (0.341796875)10

十进制数转非十进制数

对于十进制数的整数和小数转换成非十进制数的规则是不一样的:

  • 十进制整数转非十进制数:除k取余法(k 是对应进制的基数),也就是用基数相除,直到商小于 k,然后反序取余
  • 十进制小数转非十进制数:乘k取整法(k 是对应进制的基数),也就是用基数相乘,取出整数部分,再继续用小数部分乘以基数,直到小数部分为0或者达到指定的位数精度,然后正序取整

如十进制整数(48)10 转为二进制数(110000)2

48

如十进制整数(65)10 和(2467)10 转为八进制数(101)8和(463)8

2467

如十进制小数(0.125)10 和 (0.825)10 转为十六进制小数(0.2)16 和 (0.D33)16(保留三位小数精度)

0.125

非十进制数之间的相互转换

在二进制和八进制以及二进制和十六进制之间转换时,有一个规律是:
1位八进制数对应3位二进制数,而1位十六进制对应4位二进制数。 因此,在相互转换时,可遵循如下方法:

  1. 八进制数转二进制数:将每1位八进制数直接用相应的3位二进制数表示;
  2. 二进制数转八进制数:以小数点为界,整数部分向左,小数部分向右将每3位二进制数分成一组(不足3位则用0补足3位),将每一组二进制数直接用对应的1位八进制数表示;
  3. 十六进制数转二进制数:将每1位十六进制数直接用相应的4位二进制数表示;
  4. 二进制数转十六进制数:以小数点为界,整数部分向左,小数部分向右将每4位二进制数分成一组(不足4位则用0补足4位),将每一组二进制数直接用对应的1位十六进制数表示;
  5. 八进制和十六进制互转:先将其中一个转为二进制数,再按照二进制数与对应数制的转换规则进行转换。

如将(3456.2262)8 转为二进制数(11100101110.010010101010)2

img

如将(1101011.10111)2 转为八进制数(153.56)8

img

<本文完>

wdpm commented

错误出处:

如十进制整数(65)10 和(2467)10 转为八进制数(101)8和(463)8:

勘误:
$(2467)_{10}$转为八进制数$(4643)_8$