【问题标题】:How can I make an addition to two strings that contain a long number? In C如何添加两个包含长数字的字符串?在 C 中
【发布时间】:2020-04-15 13:36:12
【问题描述】:
char* a = "5880391469248794735212"
char* b = "1234567890231"

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

感谢您的帮助!

【问题讨论】:

  • 要么使用像 GMP 这样的大整数库,要么使用你在小学学过的长加法算法自己编写。

标签: c string numbers c-strings data-conversion


【解决方案1】:

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

这是我的五分钱。

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

【讨论】:

    【解决方案2】:

    您应该使用像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;
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-03
      • 1970-01-01
      • 2020-10-15
      • 2013-11-26
      • 1970-01-01
      • 1970-01-01
      • 2015-07-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多