This commit is contained in:
Kevin Cotugno 2018-10-10 16:40:47 -07:00
parent a1896bdeef
commit 93ebab379b

View File

@ -26,13 +26,23 @@
#define LSHIFT32(x) (x << BIT_SIZE)
#define RSHIFT32(x) (x >> BIT_SIZE)
#define SWAP(x, y) { void *tmp = x; x = y, y = tmp; }
typedef unsigned BOOL;
struct big_int {
uint64_t count;
uint64_t size;
uint32_t* buf;
};
void big_int_grow(struct big_int* i, int copy);
struct big_int* big_int_init(uint64_t x);
void big_int_destroy(struct big_int* i);
void big_int_internal_grow(struct big_int* i, size_t size, BOOL copy);
void big_int_grow(struct big_int* i, BOOL copy);
uint64_t big_int_bit_len(struct big_int* i);
void big_int_add(struct big_int *a, struct big_int *b);
void big_int_sub(struct big_int* a, struct big_int* b);
struct big_int* big_int_init(uint64_t x)
{
@ -53,28 +63,32 @@ void big_int_destroy(struct big_int* i)
free(i);
}
void big_int_grow(struct big_int* i, int copy)
void big_int_internal_grow(struct big_int* i, size_t size, BOOL copy)
{
uint32_t* tmp;
size_t new_size = (size_t)i->size * MEM_STEPS;
tmp = (uint32_t*)calloc(new_size, sizeof(uint32_t));
if (copy)
memcpy(tmp, i->buf, sizeof(uint32_t) * (size_t)i->size);
tmp = (uint32_t*)calloc(size, sizeof(uint32_t) * size);
if (tmp == NULL) {
printf("Unable to allocate memory");
exit(1);
}
if (copy)
memcpy(tmp, i->buf, sizeof(uint32_t) * (size_t)i->size);
i->buf = tmp;
i->size = new_size;
i->size = size;
}
void big_int_grow(struct big_int* i, BOOL copy)
{
size_t new_size = (size_t)i->size * MEM_STEPS;
big_int_internal_grow(i, new_size, copy);
}
uint64_t big_int_bit_len(struct big_int* i)
{
uint64_t j = 32;
uint32_t j = 32;
uint32_t x = i->buf[i->count - 1];
if (x <= 0x0000ffff) j -= 16, x <<= 16;
@ -121,12 +135,11 @@ void big_int_add(struct big_int *a, struct big_int *b)
i++;
} while(i < a->count || i < b->count || carry > 0);
uint32_t* tmp_ptr = a->buf;
a->buf = result->buf;
SWAP(a->buf, result->buf);
a->count = i;
a->size = result->size;
free(tmp_ptr);
big_int_destroy(result);
}
void big_int_add_uint32(struct big_int* a, uint32_t b)
@ -134,19 +147,58 @@ void big_int_add_uint32(struct big_int* a, uint32_t b)
big_int_add(a, big_int_init(b));
}
void big_int_sub(struct big_int* a, struct big_int* b)
{
struct big_int* result = big_int_init(0);
uint64_t tmp = 0;
uint64_t carry = 0;
uint64_t i = a->count + 2;
do {
uint64_t x = 0, y = 0;
if (i - 2 < a->count) {
x = (uint64_t)a->buf[i - 2];
}
x |= carry;
if (i - 2 < b->count) {
y = (uint64_t)b->buf[i - 2];
}
tmp = x - y;
result->buf[i - 1] = (uint32_t)RSHIFT32(UPPER64(tmp));
carry = LSHIFT32(LOWER64(tmp));
--i;
} while(i > 0);
SWAP(a->buf, result->buf);
a->size = result->size;
big_int_destroy(result);
}
int main(void)
{
struct big_int* bi = big_int_init(123456789);
big_int_add_uint32(bi, 123456789);
for (int i = 0; i < 1000; i++)
for (int i = 0; i < 10; i++)
big_int_add(bi, bi);
for (uint64_t i = 0; i < bi->count; i++)
printf("[%" PRIu32 "] ", bi->buf[i]);
printf("\n");
big_int_sub(bi, big_int_init(53350));
for (uint64_t i = 0; i < bi->count; i++)
printf("[%" PRIu32 "] ", bi->buf[i]);
printf("\n");
printf("%lu\n", big_int_bit_len(bi));
printf("%" PRIu64 "\n", bi->size);