C 如何求大数之和

C 如何求大数之和,c,bignum,C,Bignum,我正试图编制一个程序,这个程序将对非常大的数字求和。不幸的是,我被卡住了——它不会返回任何结果,即使我注释掉malloc和realloc(编译器似乎失败了)。有什么想法吗?我的代码: #include <stdio.h> #include <stdlib.h> #include <string.h> int i,j,x; char *actual = NULL; char *sum = NULL; void init () { sum = mall

我正试图编制一个程序,这个程序将对非常大的数字求和。不幸的是,我被卡住了——它不会返回任何结果,即使我注释掉malloc和realloc(编译器似乎失败了)。有什么想法吗?我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int i,j,x;
char *actual = NULL;
char *sum = NULL;

void init () {
    sum = malloc(500);
    actual = malloc(500);
}

void calculate (char *argv[]) {
    int rest = 0;
    actual = *argv;
    actual = realloc(actual, strlen(*argv));
    if (strlen(actual) > strlen(sum)) {
    sum = realloc(sum, strlen(actual) + 1);
    } else sum = realloc(sum, strlen(sum) + 1);
    long b;
    for (b = 1; b < strlen(actual); b++) {
        rest = rest + atoi(&sum[strlen(sum) - b]) + atoi(&actual[strlen(actual) - b]);
        if (rest > 9) {
            sum[strlen(sum) - b] = rest - 10;
            rest = 1;   // carrying over 1
        } else {
            sum[strlen(sum) - b] = rest;
            rest = 0;
        }
    }
}

void writeResult () {
    printf("VYPIS - sum:");
    printf("strlen souctu je: %lu\n",strlen(sum));
    long c;
    for (c = 0; c <= strlen(sum); c++) {
        printf("%c",sum[c]);
    }
    printf("\n");
}

void emtpy () {
    free(actual);
    free(sum);
}

int main(int argc, char * argv[]) {
    init();
    for (i = 1; i < argc; i++) {
        calculate(&argv[i]);
    }
    writeResult();
    emtpy();
    return 0;
}
#包括
#包括
#包括
int i,j,x;
char*actual=NULL;
char*sum=NULL;
void init(){
总和=malloc(500);
实际值=malloc(500);
}
计算无效值(字符*argv[]){
int-rest=0;
实际=*argv;
实际值=实际值(实际值,strlen(*argv));
如果(strlen(实际)>strlen(总和)){
sum=realloc(sum,strlen(实际)+1);
}else sum=realloc(sum,strlen(sum)+1);
长b;
对于(b=1;b9){
sum[strlen(sum)-b]=rest-10;
rest=1;//结转1
}否则{
sum[strlen(sum)-b]=剩余;
剩余=0;
}
}
}
无效写入结果(){
printf(“VYPIS-sum:”);
printf(“strlen soutu je:%lu\n”,strlen(sum));
长c;

对于(c=0;c尝试
realloc
argv
是未定义的行为。一般来说,您不应该
realloc
您没有
malloc
-ed或从显式将内存所有权转移给您的函数接收到的内容

还要注意,
atoi
需要一个以null结尾的C字符串,因此将长字符串的一部分传递给它是不正确的。如果要获取
char
数字的数值,请减去
'0'
,如下所示:

int digit = actual[strlen(actual) - b] -'0';
要将单个十进制数字转换为
字符
,请将
'0'
添加回:

res[b] = digit + '0';

您的代码太复杂,有几个问题:

  • 不能使用
    atoi
    将字符转换为值,可以非常简单地这样做:
    int value=c-“0”
  • 您不应该修改
    argv
    数组中的字符串。尤其是不能重新分配它们。这会调用未定义的行为
  • 始终为最终
    '\0'
    分配或重新分配比要存储在结果数组中的字符串长度多1个字节,并记住设置此最终字节
  • 您应该像手工操作一样,从右到左计算加法,跟踪从一个数字到下一个数字的进位,可能会添加一个额外的前导数字
下面是一个非常简化的问题版本,演示了如何处理以10为基数的大数字:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static char *bigsum(char *res, const char *arg) {
    size_t pos1, pos2, pos3, len3;
    unsigned int carry;

    pos1 = strlen(res);
    pos2 = strlen(arg);
    len3 = pos3 = (pos1 < pos2) ? pos2 + 1 : pos1 + 1;
    /* reallocate the result array to one more than the larger operand */
    res = realloc(res, len3 + 1);
    /* set the terminating '\0' at the end of result */
    res[pos3] = '\0';
    for (carry = 0; pos3 > 0; carry /= 10) {
        if (pos1 > 0) carry += res[--pos1] - '0';
        if (pos2 > 0) carry += arg[--pos2] - '0';
        res[--pos3] = '0' + carry % 10;
    }
    while (res[0] == '0' && len3 > 1) {
        /* normalize the result: remove redundant initial zeroes */
        memmove(res, res + 1, len3--);
    }
    return res;
}

int main(int argc, const char **argv) {
    /* initialize the result to "0" as an allocated string */
    char *result = strcpy(malloc(2), "0");
    int i;

    for (i = 1; i < argc; i++) {
        result = bigsum(result, argv[i]);
    }
    printf("%s\n", result);
    return 0;
}
#包括
#包括
#包括
静态字符*bigsum(字符*res,常量字符*arg){
尺寸为1号、2号、3号、透镜3号;
无符号整数进位;
pos1=strlen(res);
pos2=strlen(arg);
len3=pos3=(pos10;进位/=10){
如果(pos1>0)进位+=res[--pos1]-'0';
如果(pos2>0)进位+=arg[--pos2]-'0';
res[--pos3]=“0”+进位%10;
}
而(res[0]=“0”&&len3>1){
/*标准化结果:删除冗余的初始零*/
memmove(res,res+1,len3--);
}
返回res;
}
int main(int argc,常量字符**argv){
/*将结果初始化为“0”,作为分配的字符串*/
char*result=strcpy(malloc(2),“0”);
int i;
对于(i=1;i
始终检查可能遇到错误的函数的结果!检查对strlen()的每次调用,确保传递了有效的以NULL结尾的字符串。另一方面:
atoi
需要以NULL结尾的字符串,而不是:
atoi(&sum[strlen(sum)-b])
。若要转换单个数字,只需执行
x-“0”
“actual=*argv;”即可覆盖Init()中的指针。您有太多错误。若要修复已注意到的错误,请阅读所有这些strlen()调用中间临时变量,调试重建并使用调试器。我怀疑OP认为'actual=*argv;'复制了字符数组(我们知道它没有)。