今天只有一上午,讲的东西不多,这里就整理一下高精的东西,数论部分请见my blog
高精度:
先讲一讲进制问题:十进制的二进制表示:以10为例,
10的二进制表示为1010
10的三进制表示为101
将一个十进制的x转为k进制
要求把十进制的55转为三进制的表示
短除法如下:
3|55……1
3|18……0
3|6……0
3|2……2
0
将所有余数从下向上写出,55的三进制表示为2001
将一个k进制的数转成十进制的数
根据定义,k进制的xnxn-1xn-2……x0可以转为x·k^n+x·k^n-1+……+x·k^0
二进制、八进制、十进制、十六进制
- 计算机中最常用的进制
- 在C++中写一个二进制,只需要在前面加上一个前导0
- 十六进制:用字母对应10到15(A~F),所以0x3f3f3f3f≈1.1*10^9
高精度的目的:用C++自带的类型,十进制一旦超过20位,就无法进行运算,高精度运算的目的就是通过模拟竖式加减乘除法
高精度步骤:
(1)个位对齐
(2)逐位相加
(3)注意进位
高精度的存储:
用数组来存每一位
以19260817为例,如果按照顺序存储,就会存成19260817。这样就不能满足个位对齐的步骤,那么我们就要反着存,即71806291,这样在做加法时个位一定是对齐的
高精度的代码(钟神的写法,只需要将int a,b转换成gaojing a,b)
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 7 struct gaojing 8 { 9 int z[10010];//用来存这个数的数组,0表示个位,以此类推 10 int l;//表示这个数是一个l位的数 11 gaojing() 12 { 13 l=1; 14 memset(z,0,sizeof(z)); 15 }//构造函数,每次声明一个高精类,函数都会运行一次 16 17 friend istream& operator>>(istream &cin,gaojing &a)//意思是用cin这个读入函数读入a,friend叫做有缘函数 18 { 19 static/*在函数中开数组的局部变量,一定要加static*/ char s[10010]; 20 cin>>s; 21 int l=strlen(s); 22 for(int i=0;i<=l;++i) 23 { 24 a.z[i]=s[l-i-1]-'0'; 25 } 26 a.l=l; 27 return cin;//第17行和第27行当做模板记就行了 28 } 29 30 friend ostream&operator<<(ostream &cout,const gaojing &a) 31 { 32 for(int i=a.l-1;i>=0;i--) 33 { 34 cout<<a.z[i]; 35 } 36 return cout; 37 } 38 }; 39 //写一下需要的运算符:+ - * / % < <= > >= == != cin>> cout<< 40 //这里只对 41 //运用重载运算符 42 gaojing operator+(const gaojing &a,const gaojing &b)//定义的时高精度之间的加法,不影响正常的加法,返回类型也应该是一个高精度的数 43 //需要注意,gaojing a时,系统会对a进行备份,只在这个函数中运用,gaojing &a时,系统会直接将a的值传过来 44 //a和b是一个高精度的东西,如果不用取址符号,将会在每一次运行函数时都拷贝一个很大很大的数组,所以在a,b前边加上& 45 //但是如果手抖将a和b的值改动,应该加一个const(来自钟神的关爱),如果要将这个函数喂给STL,const是必不可少的 46 { 47 gaojing c; 48 int l=max(a.l,b.l); 49 for(int i=0;i<l;++i) 50 { 51 c.z[i]=a.z[i]+b.z[i]; 52 c.z[i+1]+=c.z[i]/10; 53 c.z[i]=c.z[i]%10;//模拟的是进位的情况 54 } 55 if(c.z[l]!=0) l++; 56 c.l=l;//检查是否有进位 57 return c; 58 } 59 60 gaojing operator*(const gaojing &a,const gaojing &b) 61 { 62 gaojing c; 63 for(int i=0;i<a.l;++i) 64 for(int j=0;j<=b.l;++j) 65 c.z[i+j]=a.z[i]*b.z[j]; 66 c.l=a.l+b.l; 67 for(int i=0;i<c.l;++i) 68 { 69 c.z[i+1]+=c.z[i]/10; 70 c.z[i]=c.z[i]%10; 71 } 72 while(c.l>0&&c.z[c.l]==0)//找第一个不等于0的c.l,这时的l为c.z[i]的长度 73 c.l--; 74 if(c.l==0) c.l++; 75 return c; 76 } 77 78 int main() 79 { 80 gaojing x,y; 81 cin>>x>>y; 82 cout<<x+y<<endl<<x*y<<endl; 83 }