我如何添加两个包含长数字的字符串?在C

问题描述 投票:-2回答:2
char* a = "5880391469248794735212"
char* b = "1234567890231"

我需要计算加法并将新数字放入字符串中。我尝试将每个数字转换为整数,将它们加在一起并将结果转换为字符串,但是数字的最大值为unsigned long long,其中不能包含我显示的数字。

谢谢您的帮助!

c string numbers c-strings data-conversion
2个回答
0
投票

您应该使用像GMP这样的大数字库,但如果愿意,也可以尝试以下代码:

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

char *add(char *x, char *y);

int main(void)
{
    char *a = "5880391469248794735212";
    char *b = "1234567890231";

    char *c = add(a, b);

    printf("z: %s\n", c);

    free(c);
    return 0;
}

void reverseString(char *buf)
{
    char *ptr = buf + strlen(buf) - 1;

    while (buf < ptr) {
        char tmp = *buf;
        *buf++ = *ptr;
        *ptr-- = tmp;
    }
}

char *add(char *a, char *b)
{
    size_t xlen = strlen(a);
    size_t ylen = strlen(b);

    size_t n = 0;

    int val;
    int r = -1;

    char *p1, *p2;
    char *t1, *t2;

    char *c = NULL;

    if (xlen >= ylen) {
        p1 = a + xlen - 1;  t1 = a;
        p2 = b + ylen - 1;  t2 = b;
        c = (char *)malloc(xlen + 2);
    }
    else {
        p1 = b + ylen - 1;  t1 = b;
        p2 = a + xlen - 1;  t2 = a;
        c = (char *)malloc(ylen + 2);
    }
    if (!c) {
        fputs("error: memory allocation failed.\n", stderr);
        return NULL;
    }

    while (p2 >= t2)
    {
        if (r == -1) {
            val = (*p1-- - '0') + (*p2-- - '0');
        }
        else {
            val = (*p1-- - '0') + (*p2-- - '0') + 1;
        }
        if (val > 9) {
            r = val - 10;
            c[n++] = r + '0';
        }
        else {
            c[n++] = val + '0';
            r = -1;
        }
    }

    while (p1 >= t1)
    {
        if (r == -1) {
            c[n++] = *p1--;
        }
        else {
            val = (*p1-- - '0') + 1;
            if (val > 9) {
                r = val - 10;
                c[n++] = r + '0';
            }
            else {
                c[n++] = val + '0';
                r = -1;
            }
        }
    }
    if (r != -1) {
        c[n++] = '1';
    }
    c[n] = '\0';
    reverseString(c);
    return c;
}

0
投票

我们,初学者,应该互相帮助。:)

这是我的五分钱。

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

int is_overflow( const char *s1, size_t n1, const char *s2, size_t n2 )
{
    const int Base = 10;

    int overflow = 0;

    while ( n1 != 0 && n2 != 0 )
    {
        overflow = !( overflow + ( s1[--n1] - '0' ) + ( s2[--n2] - '0' ) < Base );
    }

    while ( overflow && n1 != 0 )
    {
        overflow = !( overflow + ( s1[--n1] - '0' ) < Base );
    }

    while ( overflow && n2 != 0 )
    {
        overflow = !( overflow + ( s2[--n2] - '0' ) < Base );
    }

    return overflow;
}

char * add_strings_as_numbers( char *s1, size_t n1, 
                               const char *s2, size_t n2,
                               const char *s3, size_t n3 )
{
    const int Base = 10;

    int overflow = 0;

    while ( n2 != 0 && n3 != 0 )
    {
        char c = overflow + ( s2[--n2] - '0' ) + ( s3[--n3] - '0' );
        overflow = !( c < Base );
        s1[--n1] = c % Base + '0';
    }

    while ( n2 != 0 )
    {
        char c = overflow + ( s2[--n2] - '0' );
        overflow = !( c < Base );
        s1[--n1] = c % Base + '0';
    }

    while ( n3 != 0 )
    {
        char c = overflow + ( s3[--n3] - '0' );
        overflow = !( c < Base );
        s1[--n1] = c % Base + '0';
    }

    if ( overflow ) s1[--n1] = overflow + '0';

    return s1;
}

int main(void) 
{
    const char *s1 = "5880391469248794735212";
    const char *s2 = "1234567890231";
//  const char *s1 = "1";
//  const char *s2 = "999";
    const size_t N1 = strlen( s1 );
    const size_t N2 = strlen( s2 );

    size_t n = ( N1 < N2 ? N2 : N1 ) + is_overflow( s1, N1, s2, N2 ) + 1;

    char *result = calloc( n, sizeof( char ) );

    add_strings_as_numbers( result, n - 1, s1, N1, s2, N2 );

    printf(  "\"%s\" + \"%s\" = \"%s\"\n", s1, s2, result );

    free( result );

    return 0;
}

程序输出为

"5880391469248794735212" + "1234567890231" = "5880391470483362625443"

否则,最好在函数add_strings_as_numbers中直接分配一个新字符串,其显示方式如下所示。

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

static int is_overflow( const char *s1, size_t n1, const char *s2, size_t n2 )
{
    const int Base = 10;

    int overflow = 0;

    while ( n1 != 0 && n2 != 0 )
    {
        overflow = !( overflow + ( s1[--n1] - '0' ) + ( s2[--n2] - '0' ) < Base );
    }

    while ( overflow && n1 != 0 )
    {
        overflow = !( overflow + ( s1[--n1] - '0' ) < Base );
    }

    while ( overflow && n2 != 0 )
    {
        overflow = !( overflow + ( s2[--n2] - '0' ) < Base );
    }

    return overflow;
}

char * add_strings_as_numbers( const char *s1, size_t n1,
                               const char *s2, size_t n2 )
{
    const int Base = 10;

    size_t n = ( n1 < n2 ? n2 : n1 ) + is_overflow( s1, n1, s2, n2 );

    char *result = calloc( n + 1, sizeof( char ) );

    if ( result != NULL )
    {
        int overflow = 0;

        while ( n1 != 0 && n2 != 0 )
        {
            char c = overflow + ( s1[--n1] - '0' ) + ( s2[--n2] - '0' );
            overflow = !( c < Base );
            result[--n] = c % Base + '0';
        }

        while ( n1 != 0 )
        {
            char c = overflow + ( s1[--n1] - '0' );
            overflow = !( c < Base );
            result[--n] = c % Base + '0';
        }

        while ( n2 != 0 )
        {
            char c = overflow + ( s2[--n2] - '0' );
            overflow = !( c < Base );
            result[--n] = c % Base + '0';
        }

        if ( overflow ) result[--n] = overflow + '0';

    }

    return result;
}

int main(void) 
{
    const char *s1 = "5880391469248794735212";
    const char *s2 = "1234567890231";
//  const char *s1 = "1";
//  const char *s2 = "999";
    const size_t N1 = strlen( s1 );
    const size_t N2 = strlen( s2 );


    char *result = add_strings_as_numbers( s1, N1, s2, N2 );

    printf(  "\"%s\" + \"%s\" = \"%s\"\n", s1, s2, result );

    free( result );

    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.