Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

数制基础 #66

Open
dwqs opened this issue May 28, 2018 · 1 comment
Open

数制基础 #66

dwqs opened this issue May 28, 2018 · 1 comment

Comments

@dwqs
Copy link
Owner

dwqs commented May 28, 2018

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

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

在计算机系统中,我们常见的数制有四种:十进制、二进制、八进制和十六进制。当然,还有其它不常见的数制,如三进制、十二进制、二十进制以及六十进制等。不同的数制有不同的基数,在一种数制中所能使用的数码的个数称为该数值的基数。基数一般和数制类型对应,如二进制的基数为"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
Copy link

wdpm commented Apr 3, 2021

错误出处:

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

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants