数制基础
dwqs opened this issue · 1 comments
计算机的世界里只有二进制
二进制是一种数制。数制是"数据制度"的简称,是指数据的进位计数规则,表示数据逢几进位,又称"进位计数制"。如我们常用的十进制就是逢十进位,计算机中的二进制则是逢二进位。
在计算机系统中,我们常见的数制有四种:十进制、二进制、八进制和十六进制。当然,还有其它不常见的数制,如三进制、十二进制、二十进制以及六十进制等。不同的数制有不同的基数,在一种数制中所能使用的数码的个数称为该数值的基数。基数一般和数制类型对应,如二进制的基数为"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:
如十进制整数(65)10 和(2467)10 转为八进制数(101)8和(463)8:
如十进制小数(0.125)10 和 (0.825)10 转为十六进制小数(0.2)16 和 (0.D33)16(保留三位小数精度)
非十进制数之间的相互转换
在二进制和八进制以及二进制和十六进制之间转换时,有一个规律是:
1位八进制数对应3位二进制数,而1位十六进制对应4位二进制数。 因此,在相互转换时,可遵循如下方法:
- 八进制数转二进制数:将每1位八进制数直接用相应的3位二进制数表示;
- 二进制数转八进制数:以小数点为界,整数部分向左,小数部分向右将每3位二进制数分成一组(不足3位则用0补足3位),将每一组二进制数直接用对应的1位八进制数表示;
- 十六进制数转二进制数:将每1位十六进制数直接用相应的4位二进制数表示;
- 二进制数转十六进制数:以小数点为界,整数部分向左,小数部分向右将每4位二进制数分成一组(不足4位则用0补足4位),将每一组二进制数直接用对应的1位十六进制数表示;
- 八进制和十六进制互转:先将其中一个转为二进制数,再按照二进制数与对应数制的转换规则进行转换。
如将(3456.2262)8 转为二进制数(11100101110.010010101010)2:
如将(1101011.10111)2 转为八进制数(153.56)8:
<本文完>
错误出处:
如十进制整数(65)10 和(2467)10 转为八进制数(101)8和(463)8:
勘误: