0

Is it possible to add 2 big numbers without reversing the array? I must use this declaration of function:

int add(const char* n1, const char* n2, char** sum);

I cannot reverse arrays because it's cosnt char* :(

kiran Biradar
  • 12,700
  • 3
  • 19
  • 44
logic
  • 1
  • 1
  • 2
    You don't need to reverse the array to work right-to-left. – hobbs May 12 '19 at 14:37
  • Is this binary-coded decimal (where each `char` is a decimal digit `0-9`) or `base-256` or is it an arbitrary-length `base-2` integer, or something else? – Dai May 12 '19 at 14:37
  • The rightmost 'digit' in `n1` is `n1[strlen(n1)-1]`; the one before, `if (strlen(n1) > 1)`, is `n1[strlen(n1)-2]`; ... – pmg May 12 '19 at 14:53
  • addition always need to be done from the least significant digit – phuclv May 12 '19 at 15:01

1 Answers1

0

I take this as a challenge -- the following code adds two non-negative number strings from left to right. It simply takes from the longer until the numbers line up and then it adds character by character. If there's a carry it propagates it right to left fixing up already summed digits:

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

int add(const char *n1, const char *n2, char **sum) {
    const char *longer = n1, *shorter = n2; // ['1', '2', '3'] + ['8', '9']
    size_t bigger = strlen(longer), smaller = strlen(shorter); // 3, 2

    if (smaller > bigger) {
        shorter = n1;
        longer = n2;

        size_t temporary = smaller;
        smaller = bigger;
        bigger = temporary;
    }

    *sum = malloc(bigger + 2); // 3 + carry + null byte
    (*sum)[0] = '0';
    (*sum)[bigger + 1] = '\0'; // ['0', x, x, x, '\0']

    for (int power_of_ten = bigger; power_of_ten > 0; power_of_ten--) { // 3 ... 1 (for length comparison)
        size_t idx = bigger - power_of_ten; // 0 ... 2 (for indexing left to right)

        if (power_of_ten > smaller) {
            (*sum)[idx + 1] = longer[idx]; // just copy from longer to sum
        } else {
            char c = shorter[idx - (bigger - smaller)] + longer[idx] - '0'; // add
            (*sum)[idx + 1] = c;

            for (int j = idx + 1; j > 0 && (*sum)[j] > '9'; j--) { // backward carry
                (*sum)[j] -= 10;
                (*sum)[j - 1] += 1;
            }
        }
    }

    if ((*sum)[0] == '0') { // ['0', '2', '1', '2'] -> ['2', '1', '2']
        for (int j = 0; j < bigger + 1; j++) {
            (*sum)[j] = (*sum)[j + 1];
        }
    }

    return 42; // problem didn't specify what `int add(...)` returns
}

int main() {
    char a[] = "509843702", b[] = "430958709432";
    char *s;

    (void) add(a, b, &s);

    printf("%s\n", s);

    (void) free(s);

    return 1;
}

OUTPUT

> ./a.out
431468553134
>

CHECK

> dc
509843702 430958709432 + p
431468553134
>

This addition involves five carries, of which three are independent (not cascades.)

cdlane
  • 40,441
  • 5
  • 32
  • 81