简体   繁体   English

如何求大数

[英]How to sum big numbers

I am trying to put together a program, which would sum extremely big numbers. 我正在尝试编写一个程序,该程序将求和非常大的数字。 Unfortunately I am stuck - it doesn't return any result, even if I comment out malloc & realloc (where the compiler seems to be failing). 不幸的是,我被困住了-即使我注释掉malloc&realloc(编译器似乎失败了),它也不会返回任何结果。 Any ideas? 有任何想法吗? My code: 我的代码:

#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;
}

Trying to realloc argv is undefined behavior. 试图realloc argv是未定义的行为。 In general, you shouldn't realloc what you haven't malloc -ed or received from a function that explicitly transfers ownership of memory to you. 通常,您不应该重新realloc尚未进行malloc分配或从显式将内存所有权转让给您的函数中收到的内容。

Also note that atoi expects a null-terminated C string, so passing it a portion of a long string is incorrect. 还要注意atoi期望以N结尾的C字符串,因此将长字符串的一部分传递给它是不正确的。 If you would like to get the numeric value of a char digit, subtract '0' , like this: 如果要获取一个char数字的数值,请减去'0' ,如下所示:

int digit = actual[strlen(actual) - b] -'0';

To convert a single decimal digit number to a char , add '0' back: 要将单个十进制数字转换为char ,请加'0'

res[b] = digit + '0';

Your code is too complicated and it has several problems: 您的代码太复杂了,它有几个问题:

  • You cannot use atoi to convert characters into values, it can be done very simply this way: int value = c - '0' . 您不能使用atoi将字符转换为值,可以通过以下方式非常简单地完成此操作: int value = c - '0'
  • You should not modify the strings from the argv array. 您不应修改argv数组中的字符串。 Especially you cannot reallocate them. 特别是您不能重新分配它们。 This invokes undefined behaviour. 这会调用未定义的行为。
  • Always allocate or reallocate 1 more byte than the length of the string you mean to store in the resulting array for the final '\\0' and remember to set this final byte. 总是分配或重新分配比您要存储在最终数组'\\0'中的结果字符串的长度多1个字节,并记住设置此最终字节。
  • You should compute the addition from right to left, as you do by hand, keeping track of the carry from one digit to the next, potentially adding an extra leading digit. 您应该像手工操作那样从右到左计算加法,跟踪从一个数字到下一个数字的进位,可能会增加一个额外的前导数字。

Here is a much simplified version for your problem that shows how to deal with large numbers in base 10: 这是您的问题的简化版本,显示了如何处理以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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM