标签:
2.大数加减
问题描述:
在计算机中,由于处理器位宽限制,只能处理有限精度的十进制整数加减法,比如在32位宽处理器计算机中,参与运算的操作数和结果必须在-231~231-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 <string.h> //【输入】num1:字符串形式操作数1,如果操作数为负,则num1[0]为符号位‘-‘;num2:字符串形式操作数2,如果操作数为负,则num2[0]为符号位‘-‘ 【输出】result:保存加法计算结果字符串,如果结果为负,则result[0]为符号位。 void change(char * str) { int num =strlen(str); int i ; int tmp; for(i = 0;i <= (num/2 -1 ); i++) { tmp = str[i]; str[i] = str[num - i -1]; str[num -1 -i] = tmp; } } void jinwei(char *str) { int num = strlen(str); if(str[num-1] !=‘-‘) { for(int i = 0;i<num;i++ ) { if(str[i] >= 0x3a) { str[i+1]++; str[i]= str[i] - 10; if(i == num-1) { str[i+1] = ‘1‘; } } } } else { for(int i = 0;i<num-1;i++ ) { if(str[i] >= 0x3a) { str[i+1]++; str[i]= str[i] - 10; if(i == num-2) { str[i+1] = ‘1‘; str[i+2] = ‘-‘; } } } } } void jinwei2(char *str) { int num = strlen(str); for(int i =0;i<num-1;i++) { if(str[i]<0x30) { str[i+1]--; str[i]=str[i]+10; } } } void add ( const char *num1,const char *num2, char *result) { char num11[50] =""; char num22[50] =""; strcpy(num11,num1); strcpy(num22,num2); change(num11); change(num22); int i1 = strlen(num11); int i2 = strlen(num22); int imin ; int i; int flag; int t; if(num1[0] !=‘-‘ && num2[0] !=‘-‘) { i1 >= i2 ? (imin = i2 ) : (imin = i1);//得到加数字中字符串较小的 i1 >= i2 ? (flag = 2) : (flag = 1); //标志位 哪一个是较小的字符串 for(i=0;i<imin;i++) { result[i] = num11[i] + num22[i] - 0x30; } if(flag == 2) for(;i<i1;i++) result[i] = num11[i]; else if(flag == 1) for(;i<i2;i++) result[i] = num22[i]; } if(num1[0] ==‘-‘ && num2[0] ==‘-‘) { i1 >= i2 ? (imin = i2 ) : (imin = i1);//得到加数字中字符串较小的 i1 >= i2 ? (flag = 2) : (flag = 1); //标志位 哪一个是较小的字符串 for(i=0;i<imin-1;i++) { result[i] = num11[i] + num22[i] - 0x30; } if(flag == 2) for(;i<i1;i++) result[i] = num11[i]; else if(flag == 1) for(;i<i2;i++) result[i] = num22[i]; } if(num1[0] !=‘-‘ && num2[0] ==‘-‘) { change(num11); change(num22); flag = strcmp(num11,(num22+1)); if(flag > 0)//正数大于负数 { change(num11); change(num22); for(i =0;i< i1;i++) { if(i<i2-1) result[i] = num11[i] - num22[i] + ‘0‘; else result[i] = num11[i]; } } if(flag < 0)//正数小于负数 { change(num11); change(num22); for(i = 0;i<i2;i++) { if(i<i1) result[i] = num22[i] - num11[i] + ‘0‘; else result[i] = num22[i] ; } } if(flag == 0) result[0] = ‘0‘; } if(num1[0] ==‘-‘ && num2[0] !=‘-‘) { change(num11); change(num22); flag = strcmp((num11+1),num22); if(flag > 0)//正数xiao于负数 { change(num11); change(num22); for(i = 0;i<i1;i++) { if(i<i2) result[i] = num11[i] - num22[i] + ‘0‘; else result[i] = num11[i]; } } if(flag < 0)//正数da于负数 { change(num11); change(num22); for(i =0;i< i2;i++) { if(i<i1-1) result[i] = num22[i] - num11[i] + ‘0‘; else result[i] = num22[i] ; } } if(flag == 0) result[0] = ‘0‘; } } void qianyi(char *str) { int i =0; for(i = 1;i<strlen(str);i++) { str[i-1] = str[i]; } } void xianshi(char *str) { int i; if(str[0] == ‘-‘) for(i = 1;i<strlen(str);) { if(str[i] == ‘0‘) { qianyi((str+i)); str[strlen(str)-1] = ‘\0‘; } else break ; } else for(i = 0;i<strlen(str);i++) { if(str[i] == ‘0‘) qianyi((str+i)); else break ; } } int main() { char a1[] = "580"; char a2[] = "-600"; char a3[50] = ""; //char a3[] ; add(a1,a2,a3); //change(a1); if(a1[0]!=a2[0]) jinwei2(a3); else jinwei(a3); change(a3); xianshi(a3); printf("%s",a3); }
标签:
原文地址:http://www.cnblogs.com/eat-too-much/p/5674177.html