高精度运算.docx
《高精度运算.docx》由会员分享,可在线阅读,更多相关《高精度运算.docx(15页珍藏版)》请在冰豆网上搜索。
高精度运算
高精度运算(2009-02-2310:
16:
10)
[编辑][删除]
标签:
杂谈
#include
#include
#include
#defineMAX200
//比较两个用字符串存储的超长正整数的大小,若a>b,返回1;a==b,返回0;a
intCompare(constchar*a,constchar*b);
//函数功能:
利用字符串实现超长整型,高精度加法运算
voidIntAddition(char*augend,char*addend,char*sum);
//利用字符串实现超长整型,高精度减法运算
voidIntSubtration(char*minuend,char*subtrahend,char*difference);
//函数功能:
利用字符串实现超长整型,高精度乘法运算
voidIntMultiplication(char*multiplicand,char*multiplier,char*product);
//函数功能:
利用字符串实现超长整型,高精度除法运算
voidIntDivision(char*dividend,char*divisor,char*quotient,char*remainder);
//函数功能:
去掉原字符串的小数点,把浮点数转化成整数后存储到新的字符串
int Radix(char*toStr,char*fromStr);
//函数功能:
利用字符串实现超长浮点型,高精度加法运算
voidFloatAddition(char*augend,char*addend,char*sum);
//函数功能:
利用字符串实现超长浮点型,高精度减法运算
voidFloatSubtration(char*minuend,char*subtrahend,char*difference);
//函数功能:
利用字符串实现超长浮点型,高精度乘法运算
voidFloatMultiplication(char*multiplicand,char*multiplier,char*product);
//函数功能:
利用字符串实现超长浮点型,高精度除法运算
voidFloatDivision(char*dividend,char*divisor,char*quotient,intprecision);
//函数介绍:
在字符数组s中适当位置插入符号'('
voidInsert(chars[],intleft,intright);
//函数介绍:
判断当前余数是否与前面的某个余数相同,若相同,返回该余数的位置下标
intIsCycle(chara[][MAX],intlabel);
//函数功能:
利用字符串实现超长整型,高精度除法阶乘运算
voidFactorial(char*base,char*result);
//函数功能:
利用字符串实现超长整型,高精度乘方运算
voidIntPower(char*base,char*exponential,char*power);
//函数功能:
利用字符串实现超长浮点型,高精度乘方运算,注意指数为整数
voidFloatPower(char*base,char*exponential,char*power);
intmain(void)
{
chara[MAX]={0};
charb[MAX]={0};
charc[3*MAX]={0};
chard[MAX]={0};
puts("请输入第一个数:
");
gets(a);
puts("请输入第二个数:
");
gets(b);
IntAddition(a,b,c);
puts("两者之和:
");
puts(c);
IntSubtration(a,b,c);
puts("两者之差:
");
puts(c);
IntMultiplication(a,b,c);
puts("两者之积:
");
puts(c);
IntDivision(a,b,c,d);
puts("两者之商:
");
puts(c);
puts("余数:
");
puts(d);
IntPower(a,b,c);
puts("两者之乘方:
");
puts(c);
Factorial(a,c);
puts("a的阶乘:
");
puts(c);
system("pause");
return0;
}
voidIntAddition(char*augend,char*addend,char*sum)
{
intcAug[MAX]={0};//用来存储被加数的整型数组
intcAdd[MAX]={0};//用来存储加数的整型数组
intcSum[MAX]={0};//用来存储两数之和的整型数组
intlenAug=strlen(augend),lenAdd=strlen(addend);//被加数和加数字符串的长度
intlenMin=lenAuglenAug:
lenAdd;//两个加数的长度中的较小值
inti;
//逆序复制加数和被加数到整型数组(因为加法运算是从低位开始)
for(i=0;i cAug[i]=augend[lenAug-1-i]-'0';
for(i=0;i cAdd[i]=addend[lenAdd-1-i]-'0';
intcarry=0;//进位
ints=0;//两数之和
for(i=0;i{
s=cAug[i]+cAdd[i]+carry;//两个加数和进位之和作为当前位的和
cSum[i]=s%10;//存储当前位
carry=s/10;//获取进位
}
//处理加数或被加数超出长度lenMin的部分
while(i{
s=cAug[i]+carry;
cSum[i]=s%10;
carry=s/10;
i++;
}
while(i{
s=cAdd[i]+carry;
cSum[i]=s%10;
carry=s/10;
i++;
}
if(carry>0)//处理最后一个进位
cSum[i++]=carry;
intj;
for(j=0;j
sum[j]=cSum[i-1-j]+'0';
sum[i]='\0';
}
//比较两个用字符串存储的超长正整数的大小,若a>b,返回1;a==b,返回0;a
intCompare(constchar*a,constchar*b)
{
intlenA=strlen(a);
intlenB=strlen(b);
if(lenA!
=lenB)
returnlenA>lenB?
1:
-1;
else
returnstrcmp(a,b);
}
voidIntSubtration(char*minuend,char*subtrahend,char*difference)
{
if(strcmp(minuend,subtrahend)==0)//如果两数相等,返回"0"
{
strcpy(difference,"0");
return;
}
intcM[MAX]={0};//用来存储被减数的整型数组
intcS[MAX]={0};//用来存储减数的整型数组
intcD[MAX]={0};//用来存储两数之差的整型数组
intlenM=strlen(minuend),lenS=strlen(subtrahend);//被减数和减数字符串的长度
intlenMin=lenMlenM:
lenS;//两个减数的长度中的较小值
intflag;//记录结果是整数还是负数
inti;
//逆序复制减数和被减数到整型数组(因为减法运算是从低位开始),保证cM大于cS
if(Compare(minuend,subtrahend)>0)
{
flag=0;//被减数大于减数,结果为正数
for(i=0;i cM[i]=minuend[lenM-1-i]-'0';
for(i=0;i cS[i]=subtrahend[lenS-1-i]-'0';
}
else
{
flag=1;//被减数小于减数,结果为负数,此时要用subtrahend-minuend
for(i=0;i cS[i]=minuend[lenM-1-i]-'0';
for(i=0;i cM[i]=subtrahend[lenS-1-i]-'0';
}
for(i=0;i{
if(cM[i]>=cS[i])//被减数大于减数,直接相减
cD[i]=cM[i]-cS[i];
else//否则要向前借位
{
cD[i]=cM[i]+10-cS[i];
--cM[i+1];
}
}
//处理减数或被减数超出长度lenMin的部分
intlen=lenM>lenS?
lenM:
lenS;
while(i{
if(cM[i]>=0)
cD[i]=cM[i];
else
{
cD[i]=cM[i]+10;
--cM[i+1];
}
i++;
}
while(cD[i-1]==0)
i--;
intj=0;
if(flag==1)//如果被减数小于减数,返回一个负数
difference[j++]='-';
intk;
for(k=i-1;k>=0;k--,j++)//逆序存储两数之差到字符串sum
difference[j]=cD[k]+'0';
difference[j]='\0';
}
voidIntMultiplication(char*multiplicand,char*multiplier,char*product)
{
intcD[MAX]={0};//用来存储被乘数的整型数组
intcR[MAX]={0};//用来存储乘数的整型数组
intcP[MAX]={0};//用来存储两数之乘积的整型数组
chartcP[MAX]="";//用来存储两数之乘积的整型数组
intlenD=strlen(multiplicand),lenR=strlen(multiplier);//被乘数和乘数字符串的长度
inti,j,k;
//逆序复制乘数和被乘数到整型数组(因为乘法运算是从低位开始)
for(i=0;i cD[i]=multiplicand[lenD-1-i]-'0';
for(i=0;i cR[i]=multiplier[lenR-1-i]-'0';
intcarry;//进位
intmul=0;//两数之乘积
strcpy(product,"0");//先使product的值为0
for(i=0;i{
carry=0;//进位
for(j=0;j {
mul=cD[j]*cR[i]+carry;//两个乘数之积与进位相加作为当前位乘积
cP[j]=mul%10;//存储当前位
carry=mul/10;//获取进位
}
if(carry>0)//获取最后一个进位
cP[j++]=carry;
while(cP[j-1]==0)//去掉多余的0
--j;
//逆序复制当前位的乘积tP到字符串tcP
for(k=0;k tcP[k]=cP[j-1-k]+'0';
for(j=0;j
tcP[k++]='0';
tcP[k]='\0';
IntAddition(product,tcP,product);//对字符串进行加法运算
}
}
voidIntDivision(char*dividend,char*divisor,char*quotient,char*remainder)
{
if(Compare(dividend,divisor)==0)//被除数等于除数
{
strcpy(quotient,"1");
strcpy(remainder,"0");
return;
}
if(strcmp(divisor,"0")==0||Compare(dividend,divisor)<0)//被除数小于除数
{
strcpy(quotient,"0");
strcpy(remainder,dividend);
return;
}
charbuf[2]="0";//临时数组依次存储被除数的每一位数
inti,s,k;
strcpy(remainder,"");//先使product的值为空
for(i=0,k=0;dividend[i]!
='\0';i++)
{
s=0;
buf[0]=dividend[i];
strcat(remainder,buf);//接上被除数的一位数,改变当前余数
while(Compare(remainder,divisor)>=0)//连减试商
{
s++;
IntSubtration(remainder,divisor,remainder);
}
quotient[k++]=s+'0';//记录每一位得到的商值
if(strcmp(remainder,"0")==0)
strcpy(remainder,"");//使product的值为空,去掉多余的0
}
quotient[k]='\0';
//去掉多余的0
intj;
for(i=0;quotient[i]=='0';i++)
;
for(j=i;j<=k;j++)
quotient[j-i]=quotient[j];
}
int Radix(char*toStr,char*fromStr)
{
inti=0,j=0;
intlen;
while(fromStr[i]!
='.'&&fromStr[i]!
='\0')
{
toStr[j++]=fromStr[i++];
}
len=i++;//跳过小数点,并记录该位置
while(fromStr[i]!
='\0')
{
toStr[j++]=fromStr[i++];
}
returni-len-1;//记录小数点后的数字个数
}
voidFloatAddition(char*augend,char*addend,char*sum)
{
charcAug[MAX]={0};//用来存储被加数的字符串
charcAdd[MAX]={0};//用来存储加数的字符串
charcSum[MAX]={0};//用来存储两数之和的字符串
intlenAug,lenAdd,lenSum;//分别存储三个数的小数点后的数字个数
inti,topAug,topAdd;
//去掉小数点,把浮点数转化成整数后存储到新的字符串
lenAug=Radix(cAug,augend);
lenAdd=Radix(cAdd,addend);
topAug=strlen(cAug);
topAdd=strlen(cAdd);
//在小数部分较短的字符串后补零,使得两个数的小数部分长度相等
if(lenAug>lenAdd)
{
lenSum=lenAug;
for(i=lenAug-lenAdd;i>0;i--)
cAdd[topAdd++]='0';
}
else
{
lenSum=lenAdd;
for(i=lenAdd-lenAug;i>0;i--)
cAug[topAug++]='0';
}
cAdd[topAdd++]='\0';
cAug[topAug++]='\0';
//执行整数加法运算
IntAddition(cAdd,cAug,cSum);
i=strlen(cSum)-1;
while(lenSum>0&&cSum[i]=='0')//去掉小数部分多余的零
{
i--;
lenSum--;
}
cSum[i+2]='\0';
while(lenSum>0)//在适当位置插入'.’
{
cSum[i+1]=cSum[i];
i--;
lenSum--;
}
cSum[i+1]='.';
strcpy(sum,cSum);
}
voidFloatSubtration(char*minuend,char*subtrahend,char*difference)
{
if(strcmp(minuend,subtrahend)==0)//如果两数相等,返回"0"
{
strcpy(difference,"0");
return;
}
charcM[MAX]={0};//用来存储被减数的字符串
charcS[MAX]={0};//用来存储减数的字符串
charcD[MAX]={0};//用来存储两数之差的字符串
intlenM,lenS,lenD;//分别存储三个数的小数点后的数字个数
inti,topM,topS;
//去掉小数点,把浮点数转化成整数后存储到新的字符串
lenM=Radix(cM,minuend);
lenS=Radix(cS,subtrahend);
topM=strlen(cM);
topS=strlen(cS);
//在小数部分较短的字符串后补零,使得两个数的小数部分长度相等
if(lenM>lenS)
{
lenD=lenM;
for(i=lenM-lenS;i>0;i--)
cS[topS++]='0';
}
else
{
lenD=lenS;
for(i=lenS-lenM;i>0;i--)
cM[topM++]='0';
}
cM[topM++]='\0';
cS[topS++]='\0';
//执行整数减法运算
IntSubtration(cM,cS,cD);
i=strlen(cD)-1;
while(lenD>0&&cD[i]=='0')//去掉小数部分多余的零
{
i--;
lenD--;
}
cD[i+2]='\0';
while(lenD>0)//在适当位置插入'.’
{
cD[i+1]=cD[i];
i--;
lenD--;
}
cD[i+1]='.';
if(i==-1)//结果为0的情况
{
cD[0]='0';
cD[1]='.';
cD[2]='\0';
}
strcpy(difference,cD);
}
voidFloatMultiplication(char*multiplicand,char*multiplier,char*product)
{
charcD[MAX]={0};//用来存储被乘数的字符串
charcR[MAX]={0};//用来存储乘数的字符串
charcP[2*MAX]={0};//用来存储两数之乘积的字符串
intlenD,lenR,lenP;//分别存储三个数的小数点后的数字个数
//去掉小数点,把浮点数转化成整数后存储到新的字符串
lenD=Radix(cD,multiplicand);
lenR=Radix(cR,multiplier);
lenP=lenD+lenR;
IntMultiplication(cD,cR,cP);
inti=strlen(cP)-1;
while(lenP>0&&cP[i]=='0')//去掉小数部分多余的零
{
i--;
lenP--;
}
cP[i+2]='\0';
while(lenP>0&&i>=0)//在适当位置插入'