高精度

来源:互联网 发布:看淘宝衣服 编辑:程序博客网 时间:2024/04/29 21:17
/***************************************************************************************** * 整数高精度 * 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;}


原创粉丝点击