我正在尝试制作一个无限计算器(数字大小大于或小于整数),只处理字符串。
我正在做加法,但是当我需要向下一个字符报告十时遇到问题:比如9+7=16,我将在当前字符中放入6,在结果字符串的下一个字符中放入1。
这是我的代码:
char *add_inf(char *nb1, char *nb2, char *rslt)
{
if (*nb1 && *nb2)
{
*rslt = (*nb1 - '0' + *nb2 - '0' > 9 ? (*nb1 - '0' + *nb2 - '0') % 10 : *nb1 - '0' + *nb2 - '0') + *rslt - '0' + '0';
if (*nb1 - '0' + *nb2 - '0' > 9)
{
rslt++;
*rslt = '1'; //Here i put the next char to '1'
add_inf(nb1 + 1, nb2 + 1, rslt);
}
add_inf(nb1 + 1, nb2 + 1, rslt + 1);
}
return (rslt);
}
很抱歉-'0'和+'0'搞砸了,我应该做一个函数将其子化并在计算之前添加它。
当输入为nb1=“11111111”和nb2=“58856557”时,输出正确:
69967668
但当我输入nb1=“11111114”和nb2=“588856557”时,输出是:
699676611
代替将1添加到下一个字符,并具有:
69967671
它只是将“1”字符添加到我的结果字符串中。
思想?
最佳答案
一。我给你看三行代码:
*rslt = (*nb1 - '0' + *nb2 - '0' > 9 ? (*nb1 - '0' + *nb2 - '0') % 10 : *nb1 - '0' + *nb2 - '0') + *rslt - '0' + '0';
当
*nb1 - '0' + *nb2 - '0' <= 9
时,条件的真边和假边将具有相同的输出。因此,我们可以使用这一行糟糕的代码(需要实际的时间来解析),并将其重写为更清晰的代码:*rslt = ((*nb1 - '0' + *nb2 - '0') % 10) + *rslt - '0' + '0';
我们还可以使用“+”操作符进一步清理它。
*rslt += (*nb1 - '0' + *nb2 - '0') % 10;
2。您的用户输入
不清楚如何调用这个函数。我假设
rslt
是一个'0'
字符串,它至少比其他两个字符串长一个字节。三。溢出
你没有正确检查溢出。让我们看一个简单的例子:
"54" + "65"
。在第一个循环中,您将正确存储1
作为第一个结果。你将携带一个1
到下一个迭代。但是,在下一次迭代中,如果溢出,则不使用进位来测试。在这里,您的代码将显示
lhs + rhs == 9
,因此您很好。但实际上,这是lhs + rhs + carry == 10
!四。克拉斯·林德巴克说的一切。
In this answer
5个。返回值
假设您总是希望返回值指向完整的
rslt
字符串。你的代码不会那么做。溢出时,会增加rslt
的值。因此,如果前两个字符导致溢出,则返回值实际上是指向完整rslt
字符串的第二个字符的指针。6。因此…
所以如果我们把这些都放在心上,我们可以产生一些类似这样的代码。
char *add_inf(char *nb1, char *nb2, char *rslt) {
if (*nb1 && *nb2) {
int sum = (*nb1 - '0' + *nb2 - '0' + *rslt - '0');
*(rslt + 0) = (sum % 10) + '0';
if (sum / 10)
*(rslt + 1) = (sum / 10) + '0';
add_inf(nb1 + 1, nb2 + 1, rslt + 1);
}
return rslt;
}
int main() {
char nb1[] = "11111114";
char nb2[] = "58856557";
char output[] = "000000000";
add_inf(nb1, nb2, output);
printf("%s\n", output);
}
得到了和你一样的答案!怎么回事?
好吧,你的代码假设最低有效位在左边,最高有效位在右边。所以在你的字符串中,如果你想把数字100和200相加,你实际上会做
inf_add("001", "002");
如果这不是您想要的,那么您需要按相反的顺序迭代字符串!
7号。相反顺序的代码是什么样子的?
好吧,递归做有点烦人,所以我要用循环。
char *add_inf(char *nb1, char *nb2, char *rslt) {
int len = strlen(nb1);
int carry = 0;
for (int i=len - 1; i >= 0; --i) {
int sum = (nb1[i] - '0' + nb2[i] - '0' + carry);
rslt[i] = (sum % 10) + '0';
carry = (sum / 10);
}
return rslt;
}
int main() {
char nb1[] = "11111114";
char nb2[] = "58856557";
char output[] = "00000000";
add_inf(nb1, nb2, output);
printf("%s\n", output);
}
正如你可能希望的那样,这会产生:
69967671
请注意,在这段代码中,我们将字符串从字符串的末尾迭代到字符串的开头。
此外,在
return
之前,我们可以测试carry
以查看它是否为非零。如果它是非零的,我们可以断言或者其他什么来通知用户加法溢出。