把长度小,数值小的值作为减数,然后取反加入到被减数中,遍历被减数,遇到负数就加10,同时前一位减1
#include<stdio.h>
#include<string.h>
#define MAX 1000 // 大数的最大位数
/*
大数减法
参数:
num1为被减数,用字符数组保存
num2为减数
sum数组保存相减的结果 即:num1-num2=sum
返回值:返回数组sum的有效长度,即计算结果的位数
*/
int Subtraction(char num1[], char num2[], int sum[])
{
int i, j, len, blag;
char *temp;
int n2[MAX] = {0};
int len1 = strlen(num1); // 计算数组num1的长度,即大数的位数
int len2 = strlen(num2); // 计算数组num2的长度,即大数的位数
// 在进行减法之前要进行一些预处理
blag = 0; // 为0表示结果是正整数,为1表示结果是负整数
if(len1 < len2) // 如果被减数位数小于减数
{
blag = 1; // 标记结果为负数
// 交换两个数,便于计算
temp = num1;
num1 = num2;
num2 = temp;
len = len1;
len1 = len2;
len2 = len;
}
else if(len1 ==len2) // 如果被减数的位数等于减数的位数
{
// 判断哪个数大
for(i = 0; i < len1; i++)
{
if(num1[i] == num2[i])
continue;
if(num1[i] > num2[i])
{
blag = 0; // 标记结果为正数
break;
}
else
{
blag = 1; // 标记结果为负数
// 交换两个数,便于计算
temp = num1;
num1 = num2;
num2 = temp;
break;
}
}
}
len = len1>len2 ? len1 : len2; // 获取较大的位数
//将num1字符数组的数字转换为整型数且逆向保存在整型数组sum中,即低位在前,高位在后
for (i = len1-1, j = 0; i >= 0; i--, j++)
sum[j] = num1[i] - '0';
// 转换第二个数
for (i = len2-1, j = 0; i >= 0; i--, j++)
n2[j] = num2[i] - '0';
// 将两个大数相减
for (i = 0; i <= len; i++)
{
sum[i] = sum[i] - n2[i]; // 两个数从低位开始相减
if (sum[i] < 0) // 判断是否有借位
{ // 借位
sum[i] += 10;
sum[i+1]--;
}
}
// 计算结果长度
for (i = len1-1; i>=0 && sum[i] == 0; i--)
{
len = i+1;
if(blag==1)
{
sum[len] = -1; // 在高位添加一个-1表示负数
len++;
}
return len; // 返回结果的位数
}
int main()
{
int i, len;
int sum[MAX] = {0}; // 存放计算的结果,低位在前,高位在后,即sum[0]是低位
char num1[] = "987654321987654321"; // 第一个大数
char num2[] = "123456789123456789"; // 第二个大数
len = Subtraction(num1, num2, sum); // 两数相减
// 输出结果
printf("%s\n -\n%s\n =\n", num1, num2);
if(sum[i=len-1] < 0) // 根据高位是否是-1判断是否是负数
{
printf("-"); // 输出负号
i--;
}
for (; i >= 0; i--)
printf("%d", sum[i]);
printf("\n");
return 0;
}