/***************************************************************************************** * 整数高精度 * wengsht * * 基于int数组编的高精度,包括长整数+ - * / % 加减法支持非负整数 乘除支持整数域 * * 格式化操作: * Atoi( int [],char * ) 将char * 根据进制CI 转换为int[] 数组!!/第一位标记有效位数 * !!/ 不支持输入消除前导 * void outputf( int [] ) 格式化输出 * * 主要函数: * void add( int s1[],int s2[],int s3[] ) s1 + s2 = s3 加减法只支持非负整数 * void sub( int s1[],int s2[],int s3[] ) s1 - s2 = s3 ( s1<s2 符号位s[大大的数] 置) * void mul( int s1[],int s2[],int s3[] ) s1 * s2 = s3 乘除法支持负数 * void div( int s1[],int s2[],int s3[],int s4[] ) s1 / s2 = s3 ; s1 % s2 = s4 * int mod( int s[],int num ) return s % num; 一般取余的除数不超过位的 * * 辅助: * bool less( int s1[],int s2[] ) 顾名思义 * bool nolarger( int s1[],int s2[] ) * Left_move ( int s[] ) s *= CI * ******************************************************************************************/#include <iostream>#include <cstring>#include <iomanip>#include <cstdio>using namespace std;const int size = 101; //第一位(s[0])标记有效位数,最后一位标记符号位const int CI = 10000; //数组每位考虑乘法只能设那么大int s1[size],s2[size],s3[size],s4[size],s5[size],s6[size]; // s1 op s2 = s3 s1 % s2 = s4 //!! 实际上乘法时size不可能全用,想少bug把size调大就可以了 // s5/s6用于除法中暂存数据char ss[size+1]; //接收输入int d[4] = { 1,10,100,1000 };bool _less( int s1[],int s2[] ) //减法、除法比较时用{ if( s1[0] != s2[0] ) return s1[0] < s2[0]; for( int i = s1[0];i >= 1;i-- ) { if( s1[i] != s2[i] ) return s1[i] < s2[i] ; } return false;}bool nolarger( int s1[],int s2[] ){ if( s1[0] != s2[0] ) return s1[0] < s2[0]; for( int i = s1[0];i >= 1;i-- ) { if( s1[i] != s2[i] ) return s1[i] < s2[i] ; } return true;}void Left_move( int s[] ) //左移s = s * 10000{if( s[s[0]] == 0 ) return ;int l = ++s[0];for( ;l > 1;l-- ) s[l] = s[l-1];s[1] = 0;}void AtoI( int s[],char *ss ) //将ss 格式为int[]{memset( s,0,sizeof(s)*size ); s[0] = 1; int l = strlen( ss );if( ss[0] == '-' ) //处理下输入的负数, //只在* /中利用,+ - 法就不用了吧= = 挺容易在主函数中处理的{s[size-1] = 1;for( int i = 0;i < l-1;i++ ) ss[i] = ss[i+1]; l--;}int j = 0; //CI为,满进for( int i = l-1;i >= 0;i-- ){s[s[0]] = s[s[0]] + (ss[i]-'0') * d[j++];if( j > 3 && i > 0) { j = 0;s[0]++; } }}void outputf( int s[] ) //格式化输出{if( s[size-1] ) cout<<'-'; int i = s[0];cout<<s[i];for( i--;i >= 1;i-- ) cout<<setfill( '0' )<<setw(4)<<s[i]; //非最高位要补齐}void add( int s1[],int s2[],int s3[] ) //s1 + s2 = s3{memset( s3,0,sizeof(int)*size );int i = 1;while( i <= s1[0] || i <= s2[0] ) {s3[i] += ( s1[i] + s2[i] );if( s3[i++] >= CI ){s3[i]++;s3[i-1] -= CI;}}s3[0] = s3[i] > 0 ? i:i-1;}void sub( int s1[],int s2[],int s3[] ) // s1 - s2 = s3{memset( s3,0,sizeof(int)*size ); if( _less(s1,s2) ) { swap( s1,s2 ); s3[size-1] = 1; }int i = 1;while( i <= s1[0] ){s3[i] = s3[i] + s1[i] - s2[i];if( s3[i++] < 0 ) {s3[i-1] += 10000;s3[i]--;}}while( !s3[i] && i > 1 ) i--;s3[0] = i;}void mul( int s1[],int s2[],int s3[] ) // s1 * s2 == s3{memset( s3,0,sizeof(int)*size );if( s1[size-1] && !s2[size-1] || !s1[size-1] && s2[size-1] ) s3[size-1] = 1; //符号位for( int i = 1;i <= s1[0];i++ ){for( int j = 1;j <= s2[0];j++ ){int k = i+j-1;s3[k] += ( s1[i] * s2[j] );if( s3[k] > CI ) {s3[k+1] += (s3[k] / CI );s3[k] %= CI;}}}s3[0] = s1[0]+s2[0]-1;if( s3[s3[0]+1] ) s3[0]++;while( !s3[s3[0]] && s3[0] > 1 ) s3[0]--; // 去前导}long long mod ( int s[],long long num ){long long result = 0;if( !num ) return 0;if( num < 0 ) num = -num;for( int i = s[0];i >= 1;i-- ){result = (result * CI + s[i] ) % num;}if( s[size-1] ) result = -result;return result;}void div( int s1[],int s2[],int s3[],int s4[] ) //s3 -> 商s4 -> 余数{memset( s3,0,sizeof(int)*size );memset( s4,0,sizeof(int)*size );for( int i = s1[0];i >= 1;i-- ){//itoa( s1[i],ss,10 );sprintf(ss, "%d",s1[i]);AtoI( s5,ss );Left_move( s4 );memcpy( s6,s4,sizeof(int)*size );add( s6,s5,s4 );int result = 0;while( nolarger( s2,s4 ) ){memcpy( s6,s4,sizeof(int)*size );result++;sub( s6,s2,s4 );}Left_move( s3 );memcpy( s6,s3,sizeof(int)*size );sprintf(ss, "%d",result);//itoa( result,ss,10 );AtoI( s5,ss );add( s6,s5,s3 );}if( s1[size-1] && !s2[size-1] || !s1[size-1] && s2[size-1] ) s3[size-1] = 1;if( s1[size-1] && s4[s4[0]] != 0 ) s4[size-1] = 1;}int main(){ cout<<"输入两个非负整数(测试加减):";scanf("%s",ss);AtoI( s1,ss );scanf("%s",ss);AtoI( s2,ss );add( s1,s2,s3 );outputf( s3 );cout<<endl;sub( s1,s2,s3);outputf( s3 );cout<<endl;cout<<"输入两个长整数(测试乘除):";scanf("%s",ss);AtoI( s1,ss );scanf("%s",ss);AtoI( s2,ss );mul( s1,s2,s3 );outputf( s3 );cout<<endl;div( s1,s2,s3,s4 );outputf(s3);cout<<" ";outputf(s4);cout<<endl;cout<<mod( s1,222)<<endl;return 0;}