/*****************************************************************************************
* 整数高精度
* 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;
}
高精度
最新推荐文章于 2023-12-14 17:57:24 发布