Quick actions

cmd+k|ctrl+k

Navigation

Languages

bignum

Snippet info

Language

C

Visibility

public

Author

hyrious

Created

2019-12-21T04:29:40Z

Updated

2019-12-21T04:33:46Z

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

int min_(int a, int b) { return a < b ? a : b; }

int max_(int a, int b) { return a > b ? a : b; }

#define BASE 1000000000
typedef struct bignum_t bignum_t;
struct bignum_t {
    int size;
    int *data;
};
void bignum_print(bignum_t x) {
    printf("%d", x.data[x.size - 1]);
    for (int i = x.size - 2; i >= 0; --i) {
        printf("%09d", x.data[i]);
    }
}
bignum_t bignum(int x) {
    bignum_t bignum_from_size(int size);
    bignum_t ret = bignum_from_size(1);
    ret.data[0] = x;
    return ret;
}
bignum_t bignum_from_size(int size) {
    bignum_t ret = { .size = size };
    ret.data = (int *)malloc(size * sizeof(int));
    memset(ret.data, 0, size * sizeof(int));
    return ret;
}
void bignum_dispose(bignum_t x) { free(x.data); }
bignum_t bignum_resize(bignum_t ret, int size) {
    ret.data = realloc(ret.data, size * sizeof(int));
    memset(ret.data + ret.size, 0, size * sizeof(int));
    ret.size = size;
    return ret;
}
bignum_t bignum_add(bignum_t a, bignum_t b) {
    bignum_t ret = bignum_from_size(max_(a.size, b.size));
    int i, sum, carry = 0, len = min_(a.size, b.size);
    for (i = 0; i < len; ++i) {
        sum = a.data[i] + b.data[i] + carry;
        carry = sum / BASE;
        ret.data[i] = sum % BASE;
    }
    if (ret.size > len) {
        int *data = a.size < b.size ? b.data : a.data;
        for (; i < ret.size; ++i) {
            sum = carry + data[i];
            carry = sum / BASE;
            ret.data[i] = sum % BASE;
        }
    }
    if (carry) {
        ret = bignum_resize(ret, ret.size + 1);
        ret.data[i] = carry;
    }
    return ret;
}

int main() {
    bignum_t a = bignum_add(bignum(999999999), bignum(999999999));
    // the two temporary bignum(999999999) is not disposed!
    bignum_print(a);
    bignum_dispose(a);
}
INFO