相较于高精度加法,高精度减法会有一些不同,如果是num1 - num2的话,如果num1 > num2时,也就是结果为正时,只需要对每一位进行按位相减,如果不够就向下一位借位;但是如果是num1 < num2时,即结果为负时,再按上方的算法就会得到错误的结果,我们可以转换一下,num1- num2 < 0,那么num2 - num1 > 0,而且num1 - num2 = - (num2 - num1),所以在结果为负时,我么可以将减数互换,是结果为正,然后再结果前面加一个负号。
代码实现:
#include <stdio.h>
#include <string.h>void DigitReverse(char arr[])//反转字符串,以便后续计算
{int length = (int)strlen(arr);for (int i = 0; i < length / 2; i++){int temp = arr[i];arr[i] = arr[length - i - 1];arr[length - i - 1] = temp;}
}void StringTranstoNumber(char arrchar[],int arrnum[])//将字符数组转换为数字数组
{int length = (int)strlen(arrchar);for (int i = 0; i < length; i++){arrnum[i] = arrchar[i] - '0';}
}int JudgeResPorN(char arrch1[], char arrch2[],int len1,int len2)//1代表结果为负,0代表结果为正
{if (len1 > len2)//数字一位数大,则结果为正{return 0;}else if(len1 == len2)//两数字位数相等,遍历数字的每一位{for (int i = 0; i < len1; i++){if (arrch1[i] == arrch2[i])//i位上的数字相等,就继续判断后面的数位上的数字{continue;}else if(arrch1[i] > arrch2[i])//数字一的i位数字大于数字二的,则为正{return 0;}else//数字二的i位数字大于数字一的,则为正{return 1;}}}else//len1 < len2时结果为负{return 1;}
}void Calculate(int num1[], int num2[],int numsub[],int length)//计算减法部分
{int borrow = 0;//borrow为借位,只能是0或-1for (int i = 0;i < length; i++){numsub[i] = num1[i] - num2[i] + borrow;//i位的结果是两数字i位相减然后加上i - 1位的借位,这里是加0或-1if (numsub[i] < 0)//只要i位是负的,则要向i + 1位借位{borrow = -1;//借位numsub[i] = numsub[i] + 10;//借位借一作十,这一位的最终结果是十加原来的负数}else//i位是正的,就不用借位{borrow = 0;}}
}void Print(int numres[],int length)//打印部分
{int i = length + 1;while (i > 0 && numres[i] == 0)//去掉前导0{i--;}for (; i >= 0; i--){printf("%d",numres[i]);}
}void BigNumSub(char arrch1[],char arrch2[],int arrsub[])
{int len1 = (int)strlen(arrch1);int len2 = (int)strlen(arrch2);int length = len1 > len2 ? len1 : len2;int c = JudgeResPorN(arrch1, arrch2, len1, len2);//在字符串反转之前就要判断结果的正负DigitReverse(arrch1);DigitReverse(arrch2);int num1[505] = { 0 };int num2[505] = { 0 };StringTranstoNumber(arrch1,num1);StringTranstoNumber(arrch2,num2);if (c == 1)//结果为负{Calculate(num2,num1,arrsub,length);//结果为负就互换num1和num2,这样结果为正printf("-");//结果转为正后在结果前面加一个负号Print(arrsub,length);//打印结果}else//结果为正{Calculate(num1,num2,arrsub,length);//结果为正就正常计算Print(arrsub, length);//打印结果}
}int main()
{char ch1[505] = "0";char ch2[505] = "0";scanf("%s",ch1);//ch1 - ch2scanf("%s",ch2);int res[505] = {0};BigNumSub(ch1,ch2,res);
}