Super calculator in C For my mathematical research, I am to deal with very large numbers and I know that the standard C types are not going to stand a chance against them due to their limited capacity, so I decided to write a super calculator in C language in hope that I won't have to resort to a super computer.

I started with an add function that I want to be reviewed for bugs if any, and possible improvement in performance and general programming aspects. Note that, on my system, the program was able to add a number consisting of 200 million digits of 9 to the same number in 0.98 seconds, which is pretty impressive, but still, if there is anything in performance that can be enhanced, let me know. That is because the multiplication function is going to be dependent on this function, and things will get slower because multiplication is repeated addition.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;time.h&gt;

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

int main(void)
{
    clock_t t1 = clock();
    /* ............................................................................................................................. */
    size_t nd = 200 * 1000 * 1000; // 2 hundred million digits
    char *x = (char *)malloc(nd + 1);
    char *y = (char *)malloc(nd + 1);
    if (!x || !y) {
        fputs("error: memory allocation failed.\n", stderr);
        goto dismantle;
    }
    /* assign x and y */
    for (size_t i = 0; i &lt; nd; i++) {
        x[i] = '9';
        y[i] = '9';
    }
    /* NUL-terminate the arrays */
    x[nd] = '\0';
    y[nd] = '\0';
    /* add x and y */
    char *z = add(x, y);
    if (z) {
        //printf("x + y = %s\n", z);
        free(z);
    }
dismantle:
    if (x) free(x);
    if (y) free(y);
    /* ............................................................................................................................. */
    clock_t t2 = clock();
    fprintf(stderr, "time elapsed: %.4f\n", (double)(t2 - t1) / CLOCKS_PER_SEC);
    fprintf(stderr, "Press any key to continue . . . ");
    getchar();
    return 0;
}

void ReverseArray(char *buf)
{
    char tmp, *ptr = buf + strlen(buf) - 1;
    while (buf &lt; ptr) {
        tmp = *buf;
        *buf++ = *ptr;
        *ptr-- = tmp;
    }
}

char *add(char *x, char *y)
{
    /* store number of digits in size_t variables*/
    size_t xlen = strlen(x);
    size_t ylen = strlen(y);
    /* essential variables */
    char *z = NULL;
    int r = -1;
    int val, var = (xlen &gt;= ylen);
    size_t n = 0;
    /* pointers to x and y */
    char *p1, *p2;
    char *t1, *t2;
    /* assign pointers according to the value of var */
    if (var) {
        p1 = x + xlen - 1;  t1 = x;
        p2 = y + ylen - 1;  t2 = y;
        z = (char *)malloc(xlen + 2);
    }
    else {
        p1 = y + ylen - 1;  t1 = y;
        p2 = x + xlen - 1;  t2 = x;
        z = (char *)malloc(ylen + 2);
    }
    /* check for allocation failure */
    if (!z) {
        fputs("error: memory allocation failed.\n", stderr);
        return NULL;
    }
    /* stage 1 */
    while (p2 &gt;= t2)
    {
        if (r == -1) {
            val = (*p1-- - '0') + (*p2-- - '0');
        }
        else {
            val = (*p1-- - '0') + (*p2-- - '0') + 1;
        }
        if (val &gt; 9) {
            r = val - 10;
            z[n++] = r + '0';
        }
        else {
            z[n++] = val + '0';
            r = -1;
        }
    }
    /* stage 2 */
    while (p1 &gt;= t1)
    {
        if (r == -1) {
            z[n++] = *p1--;
        }
        else {
            val = (*p1-- - '0') + 1;
            if (val &gt; 9) {
                r = val - 10;
                z[n++] = r + '0';
            }
            else {
                z[n++] = val + '0';
                r = -1;
            }
        }
    }
    /* stage 3 */
    if (r != -1) {
        z[n++] = 1 + '0';
    }
    z[n] = '\0';
    ReverseArray(z);
    return z;
}
You are using textual strings to represent numbers. This is not ideal for the processor. It is better to store the numbers as arrays of 32 or 64-bit unsigned integers, depending on the type of CPU. The only issue of course is that you might have to convert from and to the textual representation for your input and output, but if you have to perform many operations on your numbers, this is a small cost to pay.

There are existing libraries that can handle very large numbers (usually called "bignums"). One of them is the GNU Multiple Precision Arithmetic library. You can use that one if you want, or look at its source code to see how they handle large numbers.