Browse Source

Infint multiplication implemented.

long_to_char
Cameron Weinfurt 1 year ago
parent
commit
9a8f1bc8ec
  1. 14
      infint.c
  2. 3
      infint.h
  3. 45
      infint_four_func.c
  4. 30
      infint_test_ff.c
  5. 29
      infint_util.c

14
infint.c

@ -42,6 +42,19 @@ void test_utils() {
infint_free(ii1);
infint_free(ii2);
ii1 = infint_new(3);
ii1->size = 3;
ii1->data[0] = 99;
ii1->data[1] = 0;
ii1->data[2] = 1;
ii2 = infint_slice(ii1, 1, 2);
assert(ii2->size == 2 && ii2->capacity == 2);
assert(ii2->data[0] == 0);
assert(ii2->data[1] == 1);
infint_free(ii1);
infint_free(ii2);
}
#include "infint_test_ff.c"
@ -52,6 +65,7 @@ void test_four_function() {
test_div();
test_add2();
test_sub2();
test_mult2();
}
void test_infint() {

3
infint.h

@ -18,11 +18,13 @@ void test_infint();
// Utility functions
infint_t *infint_new(size_t init_cap);
infint_t *infint_clone(infint_t *ii);
infint_t *infint_slice(infint_t *ii, size_t start, size_t len);
void infint_free(infint_t *ii);
char infint_grow_to(infint_t *ii, size_t size);
void infint_comp(infint_t *ii);
char infint_abs_less_than(infint_t *ii, uint8_t n);
char infint_abs_less_than2(infint_t *ii1, infint_t *ii2);
void infint_shift_right(infint_t *ii, size_t n);
// Four functions
void infint_add(infint_t *ii, uint8_t n);
@ -30,6 +32,7 @@ void infint_add2(infint_t *ii1, infint_t *ii2);
void infint_sub(infint_t *ii, uint8_t n);
void infint_sub2(infint_t *ii1, infint_t *ii2);
void infint_mult(infint_t *ii, uint8_t n);
void infint_mult2(infint_t *ii1, infint_t *ii2);
uint8_t infint_div(infint_t *ii, uint8_t n);
#endif

45
infint_four_func.c

@ -29,7 +29,7 @@ void infint_sub(infint_t *ii, uint8_t n) {
infint_comp(ii);
infint_add(ii, n);
ii->data[ii->size - 1] = 0;
while (ii->data[ii->size - 1] == 0) ii->size -= 1;
while (ii->data[ii->size - 1] == 0 && ii->size > 1) ii->size -= 1;
infint_comp(ii);
}
}
@ -60,7 +60,7 @@ uint8_t infint_div(infint_t *ii, uint8_t n) {
ii->data[i] = acc / n;
acc = (acc % n) * 100;
}
while (ii->data[ii->size - 1] == 0) ii->size -= 1;
while (ii->data[ii->size - 1] == 0 && ii->size > 1) ii->size -= 1;
return acc / 100;
}
@ -96,13 +96,50 @@ void infint_sub2(infint_t *ii1, infint_t *ii2) {
infint_comp(ii1);
infint_add2(ii1,ii2);
ii1->data[ii1->size - 1] = 0;
while (ii1->data[ii1->size - 1] == 0) ii1->size -= 1;
while (ii1->data[ii1->size - 1] == 0 && ii1->size > 1) ii1->size -= 1;
ii1->sign ^= 1;
} else {
infint_comp(ii1);
infint_add2(ii1,ii2);
ii1->data[ii1->size - 1] = 0;
while (ii1->data[ii1->size - 1] == 0) ii1->size -= 1;
while (ii1->data[ii1->size - 1] == 0 && ii1->size > 1) ii1->size -= 1;
infint_comp(ii1);
}
}
void infint_mult2(infint_t *ii1, infint_t *ii2) {
if (ii1->size == 1 && ii2->size == 1) {
uint16_t acc = ii1->data[0];
acc *= ii2->data[0];
infint_grow_to(ii1, 2);
ii1->data[0] = acc % 100;
ii1->data[1] = acc / 100;
} else if(ii1->size == 1) {
uint8_t tmp = ii1->data[0];
free(ii1->data);
ii1->data = calloc(ii2->size, sizeof(uint8_t));
memcpy(ii1->data, ii2->data, ii2->size);
ii1->capacity = ii1->size = ii2->size;
infint_mult(ii1, tmp);
} else if(ii2->size == 1) {
infint_mult(ii1, ii2->data[0]);
} else {
infint_t *acc1, *acc2;
acc2 = infint_new(ii1->size * ii2->size);
for(size_t i = 0; i < ii2->size; ++i) {
if(ii2->data[i] != 0) {
acc1 = infint_clone(ii1);
infint_mult(acc1, ii2->data[i]);
infint_shift_right(acc1, i);
infint_add2(acc2,acc1);
infint_free(acc1);
}
}
free(ii1->data);
ii1->data = acc2->data;
ii1->size = acc2->size;
ii1->capacity = acc2->capacity;
free(acc2);
}
ii1->sign ^= ii2->sign;
}

30
infint_test_ff.c

@ -175,3 +175,33 @@ void test_sub2() {
infint_free(ii1);
infint_free(ii2);
}
void test_mult2() {
infint_t *ii1, *ii2;
ii1 = infint_new(1);
ii1->data[0] = 25;
ii2 = infint_new(1);
ii2->data[0] = 50;
infint_mult2(ii1,ii2);
assert(ii1->size == 2);
assert(ii1->data[0] == 50);
assert(ii1->data[1] == 12);
infint_mult2(ii1,ii2);
assert(ii1->size == 3);
assert(ii1->data[0] == 0);
assert(ii1->data[1] == 25);
assert(ii1->data[2] == 6);
infint_mult2(ii1,ii1);
assert(ii1->size == 5);
assert(ii1->data[0] == 0);
assert(ii1->data[1] == 0);
assert(ii1->data[2] == 25);
assert(ii1->data[3] == 6);
assert(ii1->data[4] == 39);
infint_free(ii1);
infint_free(ii2);
}

29
infint_util.c

@ -13,10 +13,25 @@ infint_t *infint_clone(infint_t *ii) {
iic->size = ii->size;
iic->data = (uint8_t *) calloc(ii->capacity, sizeof(uint8_t));
iic->sign = ii->sign;
memcpy(ii->data, iic->data, ii->capacity);
memcpy(iic->data, ii->data, ii->capacity);
return iic;
}
infint_t *infint_slice(infint_t *ii, size_t start, size_t len) {
if (start >= ii->size)
len = 0;
else if (start + len >= ii->size)
len = ii->size - start;
infint_t *slice = (infint_t *) malloc(sizeof(infint_t));
slice->capacity = len;
slice->size = len;
slice->sign = 0;
slice->data = (uint8_t *) calloc(len, sizeof(uint8_t));
memcpy(slice->data, ii->data + start, len);
return slice;
}
void infint_free(infint_t *ii) {
free(ii->data);
free(ii);
@ -40,8 +55,8 @@ char infint_grow_to(infint_t *ii, size_t size) {
}
void infint_comp(infint_t *ii) {
for (int i = 0; i < ii->size; ++i)
ii->data[i] = 100 - ii->data[i];
for (int i = 0; i < ii->size; ++i)
ii->data[i] = 100 - ii->data[i];
}
char infint_abs_less_than(infint_t *ii, uint8_t n) {
@ -57,3 +72,11 @@ char infint_abs_less_than2(infint_t *ii1, infint_t *ii2) {
return ii1->data[ii1->size-1] < ii2->data[ii1->size-1];
}
}
void infint_shift_right(infint_t *ii, size_t n) {
if(n > 0) {
infint_grow_to(ii, ii->size + n);
memmove(ii->data + n, ii->data, ii->size);
memset(ii->data, 0, n);
}
}
Loading…
Cancel
Save