问题描述:
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,参与运算的操作数和结果必须在-2^31~2^31-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下:
9876543210 + 1234567890 = ?
让字符串 num1="9876543210",字符串 num2="1234567890",结果保存在字符串 result = "11111111100"。
-9876543210 + (-1234567890) = ?
让字符串 num1="-9876543210",字符串 num2="-1234567890",结果保存在字符串 result = "-11111111100"。
要求编程实现上述高精度的十进制加法。
要求实现函数:
void add (const char *num1, const char *num2, char *result)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1[0]为符号位'-'
num2:字符串形式操作数2,如果操作数为负,则num2[0]为符号位'-'
【输出】result:保存加法计算结果字符串,如果结果为负,则result[0]为符号位。
注:
I、 当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;
II、输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;
III、要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
示例
输入:num1 = "580",num2 = "-50" 输出:result = "530"
输入:num1 = "580",num2 = "-600" 输出:result = "-20"
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,参与运算的操作数和结果必须在-2^31~2^31-1之间。如果需要进行更大范围的十进制整数加法,需要使用特殊的方式实现,比如使用字符串保存操作数和结果,采取逐位运算的方式。如下:
9876543210 + 1234567890 = ?
让字符串 num1="9876543210",字符串 num2="1234567890",结果保存在字符串 result = "11111111100"。
-9876543210 + (-1234567890) = ?
让字符串 num1="-9876543210",字符串 num2="-1234567890",结果保存在字符串 result = "-11111111100"。
要求编程实现上述高精度的十进制加法。
要求实现函数:
void add (const char *num1, const char *num2, char *result)
【输入】num1:字符串形式操作数1,如果操作数为负,则num1[0]为符号位'-'
num2:字符串形式操作数2,如果操作数为负,则num2[0]为符号位'-'
【输出】result:保存加法计算结果字符串,如果结果为负,则result[0]为符号位。
注:
I、 当输入为正数时,'+'不会出现在输入字符串中;当输入为负数时,'-'会出现在输入字符串中,且一定在输入字符串最左边位置;
II、输入字符串所有位均代表有效数字,即不存在由'0'开始的输入字符串,比如"0012", "-0012"不会出现;
III、要求输出字符串所有位均为有效数字,结果为正或0时'+'不出现在输出字符串,结果为负时输出字符串最左边位置为'-'。
示例
输入:num1 = "580",num2 = "-50" 输出:result = "530"
输入:num1 = "580",num2 = "-600" 输出:result = "-20"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void reverse(char *p)//result中存的是低位到高位的结果,将其逆置,得到最终的结果
{
int len = strlen(p);
char t;
for(int i=0;i<len/2;i++)
{
t = p[i];
p[i] = p[len-i-1];
p[len-i-1] = t;
}
p[len]='\0';
}
void two_positive(const char *num1, const char *num2, char *result)//如果两个数都是正数
{
int count=0;
int carry=0;//进位
int sum=0;
int t1 = strlen(num1);
int t2 = strlen(num2);
int end1 = t1-1;
int end2 = t2-1;
//char *r_num1,*r_num2;
//reverse(num1,t1);
//reverse(num2,t2);
while( end1>=0 && end2>=0)
{
sum = num1[end1]-'0' + num2[end2]-'0' + carry;//字符转化为数字,减'0',数字转化为字符,加'0'
if(sum>=10)
{
carry = 1;
sum = sum-10;
}
else
carry = 0;
result[count++] = sum + '0';
end1--;
end2--;
}
if(end1>=0)
{
sum = num1[end1]-'0' + carry;
if(sum>=10)
{
carry = 1;
sum = sum-10;
}
else
carry = 0;
result[count++] = sum + '0';
}
if(end2>=0)
{
sum = num2[end2]-'0' + carry;
if(sum>=10)
{
carry = 1;
sum = sum-10;
}
else
carry = 0;
result[count++] = sum + '0';
}
if(carry==1)
result[count++] = '1';
result[count] = '\0';
}
void sub(const char *big,const char *small,char *result)//一正一负时,对应位相减的方式
{
int t1 = strlen(big);
int t2 = strlen(small);
int borrow = 0;//借位
int diff=0;//相应位上的差
int count=0;
int end1 = t1-1;
int end2 = t2-1;
while(end1>=0 && end2>=0)
{
int k1 = (big[end1]-'0')-borrow;
int k2 = small[end2]-'0';
if( k1 >= k2 )
{
diff = k1-k2;
borrow = 0;
}
else
{
diff = k1+10-k2;
borrow = 1;
}
result[count++] = diff+'0';
end1--;
end2--;
}
while(end1>=0)//当一个数比另一个位数多时,计算多出的位数的结果。
{
int k1 = big[end1]-'0'- borrow;
if( k1 != 0 )
result[count++] = k1+'0';
end1--;
}
while(result[count-1] == '0' && count!=1)//清除多余的0
--count;
result[count]='\0';
}
void two_positive_negative(const char *positive,const char *negative,char *result)//一正一负时计算结果
{
int t1 = strlen(positive);
int t2 = strlen(negative+1);
if(t1<t2)
{
result[0] = '-';
sub(negative+1,positive,result+1);
}
if(t1==t2)
{
if(strcmp(positive,negative+1)>0)
sub(positive,negative+1,result);
else
{
result[0] = '-';
sub(negative+1,positive,result+1);
}
}
if(t1>t2)
sub(positive,negative+1,result);
}
void add (const char *num1, const char *num2, char *result)
{
if( num1[0]!='-' && num2[0]!='-' )//两个正数求和
{
two_positive(num1,num2,result);
reverse(result);
}
if( num1[0]=='-' && num2[0]=='-' )//两个负数求和,转化为两个正数求和
{
result[0] = '-';
result = result+1;
two_positive(num1+1,num2+1,result);
reverse(result);
}
if( num1[0] != '-' && num2[0] == '-' )//num1正数,num2负数
{
two_positive_negative(num1,num2,result);
if(result[0]=='-')
reverse(result+1);
else
reverse(result);
}
if( num1[0] == '-' && num2[0] != '-' )//num1负数,num2正数
{
two_positive_negative(num2,num1,result);
if(result[0]=='-')
reverse(result+1);
else
reverse(result);
}
}
int main()
{
char *num1 = "232324232341325423532";
char *num2 = "-2512345364546143465456";
int len = strlen(num1)>strlen(num2)?strlen(num1):strlen(num2);
char *result = (char*)malloc(sizeof(char)*len);//这个地方必须限制长度,如果写成char *result = (char*)malloc(sizeof(char));
//就会出现单步调试可以得到正确结果,但直接运行时,出现内存不能读写的错误。
//这样的错误很麻烦,所以用地址时千万要小心,感觉得自己分配好,不能让指针变量随便指。
add(num1, num2,result);
printf("%s\n",result);
system("pause");
return 0;
}