c语言中int类型通常为32位,double类型为64,但不管多少位,能表达的数据还是有限的。对于超大数据的加法,如果通过转换为实际int或double类型值肯定是不行的,这时就需要考虑使用字符串方式,逐位相加来实现大数加法。
遇到一个问题,描述如下
题目描述
求2个浮点数相加的和题目中输入输出中出现浮点数都有如下的形式:
P1P2…Pi.Q1Q2…Qj
对于整数部分,P1P2…Pi是一个非负整数
对于小数部分,Qj不等于0关于输入
第1行是测试数据的组数n,每组测试数据占2行,分别是两个加数。每组测试数据之间有一个空行,每行数据不超过100个字符关于输出
n行,每组测试数据有一行输出是相应的和。输出保证一定是一个小数部分不为0的浮点数例子输入
2
0.111111111111111111111111111111
0.11111111111111111111111111111110000000.655555555555555555555555555555
1.444444444444444444444444444445
例子输出
0.222222222222222222222222222222
10000002.1
浮点数包含整数与小数部分,小数部分需要补齐低位,而整数部分需要补齐高位。
所以计算小数相加时,从字符串末尾开始遍历,处理累加,并用变量flag保存进位标识。这里还要处理如果小数相加后末尾为0部分需要截取掉。最后返回flag进位标识,用于计算整数部分。
int decimalAdd(char *str1, char *str2, char *str3)
{
int l1 = (str1 == NULL ? 0 : strlen(str1));
int l2 = (str2 == NULL ? 0 : strlen(str2));
int flag = 0; // 是否进位
int i = l1 > l2 ? l1 : l2;
int j = 0;
while (i > 0) {
int t = flag;
if (i <= l1) {
t += str1[i - 1] - '0';
}
if (i <= l2) {
t += str2[i - 1] - '0';
}
if (t % 10 != 0 || j != 0) { // 过滤末尾的0
str3[j++] = '0' + (t % 10);
}
flag = t / 10;
--i;
}
if (j == 0) {
str3[j] = '0';
}
return flag;
}
计算整数部分时,从字符串末尾遍历累加,并注意处理高位补齐问题。最后的进位不要忘记保存。
void subAdd(char *str1, char *str2, int flag, char *str3)
{
int l1 = (str1 == NULL ? 0 : strlen(str1));
int l2 = (str2 == NULL ? 0 : strlen(str2));
int i = 1;
for (; i <= l1 || i <= l2; ++i) {
int t = flag;
if (i <= l1) {
t += str1[l1 - i] - '0';
}
if (i <= l2) {
t += str2[l2 - i] - '0';
}
str3[i - 1] = '0' + (t % 10);
flag = t / 10;
}
if (flag) {
str3[i - 1] = '0' + flag;
}
return;
}
最后程序主题部分,读取两个浮点数之后,分别截取整数、小数部分并相加处理。最后反转最终结果字符串即为相加结果。
void add(char *str1, char *str2, char *str3)
{
int l1 = strlen(str1);
int l2 = strlen(str2);
char *p1 = strchr(str1, '.'); // 整数部分
char *decimal1 = NULL;
if (p1 != NULL) {
*p1 = '\0';
decimal1 = p1 + 1;
}
char *p2 = strchr(str2, '.');
char *decimal2 = NULL;
if (p2 != NULL) {
*p2 = '\0';
decimal2 = p2 + 1;
}
int flag = decimalAdd(decimal1, decimal2, str3);
int tlen = strlen(str3);
str3[tlen] = '.';
subAdd(str1, str2, flag, str3 + tlen + 1);
// 反转str3
for (int i = 0, j = strlen(str3) - 1; i < j; ++i, --j) {
char t = str3[i];
str3[i] = str3[j];
str3[j] = t;
}
printf("%s\n", str3);
}
本文介绍如何在C语言中处理大数加法,特别是涉及浮点数时,由于C语言的标准类型限制,需要将数字作为字符串处理。通过逐位相加的方法,实现了包括整数和小数部分的浮点数相加。具体实现中,先处理小数部分,从字符串末尾开始累加并处理进位,然后处理整数部分,同样从末尾开始累加并考虑高位补零。最后,将结果字符串反转得到正确答案。
1万+

被折叠的 条评论
为什么被折叠?



