您的位置:首页 > 其它

高精度计算----减法运算(浮点型)

2014-08-13 14:50 190 查看
基于上一贴,修改减法运算适合于高精度浮点型计算。
因为减法比加法难度大一点,考虑的地方也要多一些,可能代码有欠缺,欢迎指出。

运算说明:

1、相减函数依旧没改变,包括上一贴的判断被减数与减数的大小函数也没变。

2、增加两个函数,取小数位数函数和结果处理(回归小数点)函数

3、与加法浮点高精度运算相比,这里改变较多的是结果处理函数,加法加完后,位数不减反增,而且最多增一位。减法会消失掉好多位,对于浮点型,即小数点后面的数,又得把零补回来,故函数增加了几个判断,具体看代码的注释说明。

程序测试效果如下:



以下代码包含四个函数功能,皆有注释:

[cpp]
view plaincopyprint?

#include "stdio.h"
#include "string.h"

/************************************************************************/
/* 高精度减法 (这个函数要a[]>=b[]) */
/* a[]被减数数组,位数不限 */
/* b[]减数数组,位数不限 */
/* back[]结果数组,位数不会大于a[]数组的 */
/************************************************************************/
void sub(char a[],char b[],char back[])
{
int i,k,l1,l2;
l1=strlen(a);
l2=strlen(b);
back[l1]='/0';
for (i=l2-1,l1--;i>=0;l1--,i--) //减数的个数小于等于被减数,所以减的次数依减数而定

{
if (a[l1]-b[i]>=0) //不需要借位相减

{
back[l1]=a[l1]-b[i]+'0';
}
else //向前一位借1

{
back[l1]=10+a[l1]-b[i]+'0';
if (a[l1-1]!='0') //当前一位非0,可以被借时,直接借来

{
a[l1-1]-=1;
}
else //若前一位为0,则无法借到,继续向前一位的前一位借,循环

{
k=l1-1;
while (a[k]=='0')
{
a[k]='9'; //前一位的0,就变成了10,扣去被后一位借去的,还有9

k--;
}
a[k]-=1; //到达可以借的位置

}
}
}
while (l1>=0) //被减数多于减数的位数直接赋给结果数组

{
back[l1]=a[l1];
l1--;
}
while (back[0]=='0') //将结果数组往前移,方便以后的操作

{
l1=strlen(a);
for (i=0;i<l1-1;i++)
{
back[i]=back[i+1];
}
back[l1-1]='/0';
}
if (strlen(back)==0) //被减数与减数刚好相减为0的情况

{
back[0]='0';
back[1]='/0';
}
}

/************************************************************************/
/* 判断函数(被减数与减数的大小比较) */
/* 可以用strcmp函数比较字符串 */
/* 比较完后,若小于减数,则置换带入高精度减法函数,最后加'-'输出 */
/************************************************************************/
bool isBigger(char a[],char b[])
{
int l1,l2;
l1=strlen(a);
l2=strlen(b);
if (l1>l2)
{
return true;
}
else if (l1<l2)
{
return false;
}
else
{
if (strcmp(a,b)>=0)
{
return true;
}
else
{
return false;
}
}
}

/************************************************************************/
/* 函数功能:返回小数点后的个数,并修改a,b数组为正整型 */
/* 先找出小数点的位置,比较小数点后的个数,返回比较大的个数,不足的那个补0 */
/************************************************************************/
int decimal(char a[],char b[])
{
int i,j,k,l1,l2;
l1=strlen(a);
l2=strlen(b);
for (i=0;i<l1;i++)
{
if (a[i]=='.') //找到小数点位置,然后删除小数点

{
for (k=i;k<l1;k++)
{
a[k]=a[k+1];
}
l1--; //长度减少

break;
}
}
for (j=0;j<l2;j++)
{
if (b[j]=='.')
{
for (k=j;k<l2;k++)
{
b[k]=b[k+1];
}
l2--;
break;
}
}
k=(l1-i)-(l2-j); //比较两个数组谁的小数位更多

if (i==l1 && j==l2) //都没有小数点的话,返回0

{
return 0;
}
else if (k>=0) //被减数更多,b[]数组后面对齐补0

{
while (k!=0)
{
b[l2++]='0';
k--;
}
return l1-i; //返回a[]的小数位数

}
else if (k<0) //减数更多,a[]数组后面对齐补0

{
k=k*-1; //记住k要变为正的

while (k!=0)
{
a[l1++]='0';
k--;
}
return l2-j;
}
}

/************************************************************************/
/* 处理结果数组 */
/* 将数组小数点后面的后移,插入小数点 */
/* 处理小数点某位0的情况,要去掉,若是小数点后不含任何数,小数点也要去掉 */
/************************************************************************/
void result(char c[],int n)
{
int i,j,k,length;
length=strlen(c);
if (length==1 && c[0]=='0') //结果为0的话,不再处理,直接退出

{
return ;
}
if (length<n) //结果的长度小于小数位数,则前面不止要补小数点还得补0

{
j=n+2;
for (i=length-1;i>=0;i--)
{
c[--j]=c[i];
}
c[0]='0';
c[1]='.';
for (i=2;i<j;i++)
{
c[i]='0';
}
}
else //结果长度大于等于小数点,插入小数点即可(等于时再补个0)

{
for (i=length;i>length-n;i--) //数组后移length-n大小

{
c[i]=c[i-1];
}
c[length-n]='.'; //插入小数点

for (i=length;i>=length-n;i--)
{
if (c[i]!='0' && i!=length-n) //当不在小数点上面的时候,不为0直接退出

{
break;
}
else //将0置为结束符,包括特定情况时去掉小数点

{
c[i]='/0';
}
}
length=strlen(c);
if (c[0]=='.') //小数点在第一位的话要后移,左补0

{
for (i=length;i>0;i--)
{
c[i]=c[i-1];
}
c[0]='0';
}
}
}

/************************************************************************/
/* 主函数调用 */
/************************************************************************/
int main()
{
int n,k;
char a[1000],b[1000],c[1000];
printf("%s","计算次数: ");
scanf("%d",&n);
while (n--)
{
memset(a,'/0',sizeof(a));
memset(b,'/0',sizeof(b));
memset(c,'/0',sizeof(c));
printf("%s","被减数: ");
scanf("%s",&a);
printf("%s","减数: ");
scanf("%s",&b);
k=decimal(a,b); //处理小数点

if (isBigger(a,b)) //处理被减数与减数的大小

{
sub(a,b,c); //相减操作

if (k!=0)
{
result(c,k); //当是浮点数的话,对结果数组进行处理

}
printf("%s%s/n/n","结果为: ",c);
}
else
{
sub(b,a,c);
if (k!=0)
{
result(c,k);
}
printf("%s%c%s/n/n","结果为: ",'-',c);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: