数论——进制
进制
我们平时用的数字都是逢十进一的,称为十进制,逢b进一的计数规则就叫b进制。记作\((Num)_b\)。如\((100110)_2\)为二进制数字100110
。b称为基数。
如何转换
我们主要注重任何进制和十进制之间的转换。
b进制展开式
设有一b进制数\((a_k\ a_{k-1}\ a_{k-2}\ ... \ a_0)_b\),下面这个式子可以将它转换成十进制数n。
转换到b进制
把一十进制数n转换成b进制,首先我们要构造这样的式子:
这就是上一篇笔记的求余运算嘛,我们得到了两个新的数,商q和余数r。
然后,我们再递归构造上面的式子,把q当作n:
直到最后除不下去了,我们把之前的余数反向组合起来,\((r_k\ r_{k-1}\ r_{k-2}\ ...\ r_0)_{b}\)就是结果。
举个例子
n进制转m进制
先思考一个简单的办法,现在我们已经掌握了任意进制到10进制的转换,也掌握了十进制到任意进制的转换,那么对于n,我们可以先把它转换成10进制,再把这个十进制数转换成m进制,不就好了吗。
C++代码
#include "iostream"
#include "string"
#include "cmath"
using namespace std;
int n2t(int src,int base){
int result = 0;
int level = 0;
while(src!=0){
int x = src%10;
src = src / 10;
result += x * pow(base,level++);
}
return result;
}
int t2n(int src,int target_base){
int result = 0;
int level = 0;
while(src!=0){
int mod = src % target_base;
src = src / target_base;
result = mod * pow(10,level++) + result;
}
return result;
}
int n2m(int src,int base,int target_base){
if(target_base==10)
return n2t(src,base);
else if(base == 10)
return t2n(src,target_base);
else{
return t2n(n2t(src,base),target_base);
}
}
int main(){
cout << n2t(120,8) << endl;
cout << t2n(80,8) << endl;
cout << n2m(16,8,2) << endl;
return 0;
}
这段代码只能完成2~10进制的任意转换,因为使用的是int类型,无法表述10进制以上的数了,可以使用字符串解决这个问题。
有没有更简单的办法呢?其实有。
我们常用的进制就是二进制,八进制,十进制,十六进制。对于八进制,因为\(8=2^3\),所以1位八进制数可以完整的用3位二进制来表示,这样就可以建立一对一关系。而十六进制也是一样的,1位十六进制可以完整的用4位二进制来表示。
二进制 | 八进制 | 十六进制 |
---|---|---|
000 | 0 | 0 |
001 | 1 | 1 |
010 | 2 | 2 |
011 | 3 | 3 |
100 | 4 | 4 |
101 | 5 | 5 |
110 | 6 | 6 |
111 | 7 | 7 |
1000 | 10 | 8 |
1001 | 11 | 9 |
1010 | 12 | A |
1011 | 13 | B |
1100 | 14 | C |
1101 | 15 | D |
1110 | 16 | E |
1111 | 17 | F |
我们几个八进制来举例,比如\((12)_8\),我们先查\((1)_8\),发现\((1)_8=(001)_2\),然后查\((2)_8=(010)_2\),所以\((12)_8\)就是把每个八进制位对应的二进制数简单的做字符串相加即可得到\((12)_8=(001010)_2\),去除前面的00,查表发现结果是正确的。十六进制也是一样,不演示了。
所以有了这个理论基础,对于二的幂次作为基数的进制,我们可以直接建立一个表,让计算机去查表,这样就可以更快的完成运算。
伪代码
h2b_table = {0->0000,1->0001,...,F->1111}
function h2b(hexString): string
result = ""
for each char c in hexString
result += h2b_table[c];
return removeFrontSpace(result)