本文主要是介绍高精度计算----减法运算(浮点型),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基于上一贴,修改减法运算适合于高精度浮点型计算。因为减法比加法难度大一点,考虑的地方也要多一些,可能代码有欠缺,欢迎指出。
运算说明:
1、相减函数依旧没改变,包括上一贴的判断被减数与减数的大小函数也没变。
2、增加两个函数,取小数位数函数和结果处理(回归小数点)函数
3、与加法浮点高精度运算相比,这里改变较多的是结果处理函数,加法加完后,位数不减反增,而且最多增一位。减法会消失掉好多位,对于浮点型,即小数点后面的数,又得把零补回来,故函数增加了几个判断,具体看代码的注释说明。
程序测试效果如下:
以下代码包含四个函数功能,皆有注释:
- #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;
- }
这篇关于高精度计算----减法运算(浮点型)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!