Search code examples
cbignum

using array to store big numbers


i'm newbie in C programming . i have written this code for adding two numbers with 100 digits , but i don't know why the code does not work correctly , it suppose to move the carry but it doesn't . and the other problem is its just ignoring the first digit (most significant digit) . can anybody help me please ?

#include <stdio.h>
#include <ctype.h>
int sum[101] = {0};
int add(int a, int b);

void main()
{
    static int a[100];
    static int b[100];
    char ch;
    int i = 0;
    int t;
    for (t = 0; t != 100; ++t)
    {
        a[t] = 0;
    }
    for (t = 0; t != 100; ++t)
    {
        b[t] = 0;
    }
    do
    {
        ch = fgetc(stdin);
        if ( isdigit(ch) )
        {
            a[i] = ch - 48;
            ++i;
        }
        else
            break;
    }
    while (ch != '\n' || i == 100 || i != '\0');
    i = 0;
    do
    {
        ch = fgetc(stdin);
        if ( isdigit(ch) )
        {
            b[i] = ch - 48;
            ++i;
        }
        else
            break;
    }
    while (ch != '\n' || i == 100 || i != '\0');

    for (;i!=0; --i)
    {
        add(a[i], b[i]);
    }

    for (i==0;i != 101; ++i)
    {
        printf("%d", sum[i]);
    }
}

int add( int a , int b)
{
    static int carry = 0;
    float s = 0;
    static int p = 101;

    if (0 <= a+b+carry <= 9) 
    {
        sum[p] = (a + b + carry);
        carry = 0;
        --p;
        return 0;
    }
    else
    {
        if (10 <= a+b+carry < 20)
        {
        s = (((a+b+carry)/10.0 ) - 1) * 10 ;
        carry = ((a+b+carry)/10.0) - (s/10);
        }
        else 
        {
            s = (((a+b+carry)/10 ) - 2) * 10;
            carry = ((a+b+carry)/10.0) - (s/10);
        }
        sum[p] = s;
        --p;
        return 0;
    }
}

Solution

  • Your input loops have serious problem. Also you use i to count the length of both a and b, but you don't store the length of a. So if they type two numbers that are not equal length then you will get strange results.

    The losing of the first digit is because of the loop:

    for (;i!=0; --i)
    

    This will execute for values i, i-1, i-2, ..., 1. It never executes with i == 0. The order of operations at the end of each iteration of a for loop is:

    • apply the third condition --i
    • test the second condition i != 0
    • if test succeeded, enter loop body

    Here is some fixed up code:

    int a_len;
    
    for (a_len = 0; a_len != 100; ++a_len)
    {
        int ch = fgetc(stdin);   // IMPORTANT: int, not char
    
        if ( ch == '\n' || ch == EOF )
            break;
    
        a[a_len] = ch;
    }
    

    Similarly for b. In fact it would be a smart idea to make this code be a function, instead of copy-pasting it and changing a to b.

    Once the input is complete, then you could write:

    if ( a_len != b_len )
    {
        fprintf(stderr, "My program doesn't support numbers of different length yet\n");
        exit(EXIT_FAILURE);
    }
    
    for (int i = a_len - 1; i >= 0; --i) 
    {
        add(a[i], b[i]);
    }
    

    Moving onto the add function there are more serious problems here:

    • It's not even possible to hit the case of sum being 20
    • Do not use floating point, it introduces inaccuracies. Instead, doing s = a+b+carry - 10; carry = 1; achieves what you want.
    • You write out of bounds of sum: an array of size [101] has valid indices 0 through 100. But p starts at 101.

    NB. The way that large-number code normally tackles the problems of different size input, and some other problems, is to have a[0] be the least-significant digit; then you can just expand into the unused places as far as you need to go when you are adding or multiplying.