Browse Source

Division and some fixes for other functions

long_to_char
Cameron Weinfurt 3 years ago
parent
commit
c14107afb4
  1. 14
      Makefile
  2. 98
      infint.c
  3. 2
      infint.h
  4. 5
      main.c

14
Makefile

@ -1,22 +1,24 @@
objs = main.o token.o expr.o parse.o infint.o
flags = -g
build: $(objs)
clang -o infcalc $(objs) -g -O2
clang -o infcalc $(objs) $(flags)
clean:
rm *.o infcalc
main.o: main.c expr.h
clang -c main.c -o main.o -g -O2
clang -c main.c -o main.o $(flags)
token.o: token.c token.h
clang -c token.c -o token.o -g -O2
clang -c token.c -o token.o $(flags)
expr.o: expr.c expr.h
clang -c expr.c -o expr.o -g -O2
clang -c expr.c -o expr.o $(flags)
parse.o: parse.c parse.h token.h expr.h
clang -c parse.c -o parse.o -g -O2
clang -c parse.c -o parse.o $(flags)
infint.o: infint.c infint.h
clang -c infint.c -o infint.o -g -O2
clang -c infint.c -o infint.o $(flags)

98
infint.c

@ -114,15 +114,16 @@ char infint_sub(infint_t *ii, uint64_t n) {
else {
ii->data ^= -1;
ii->data += n;
if (ii->next) {
if (ii->next && ii->data < n) {
do {
ii = ii->next;
ii->data ^= -1;
ii->data += 1;
} while (ii->data < 1);
}
while(ii->next != NULL) {
ii = ii->next;
ii->data ^= -1;
while(ii->prev != NULL) {
ii = ii->prev;
ii->data ^= -1;
}
while (ii->data == 0) {
@ -166,9 +167,9 @@ char infint_sub2(infint_t *ii1, infint_t *ii2) {
// small amount of inline assembly was used to enforce this feature with the
// cost of this program now only working on 64bit x86 machines.
void infint_mult(infint_t *ii, uint64_t n) {
uint64_t carry = 0;
do {
asm (
uint64_t carry = 0;
do {
asm (
"movq (%1), %%rax\n"
"imulq %2\n"
"addq %0, %%rax\n"
@ -178,14 +179,14 @@ void infint_mult(infint_t *ii, uint64_t n) {
: "+rm" (carry)
: "rdi" (ii), "rsi" (n)
: "rax", "rdx"
);
if(ii->next == NULL) {
if(carry)
infint_push(ii, carry);
return;
}
ii = ii->next;
} while(1);
);
if(ii->next == NULL) {
if(carry)
infint_push(ii, carry);
return;
}
ii = ii->next;
} while(1);
}
void infint_mult2(infint_t *ii1, infint_t *ii2) {
@ -209,8 +210,75 @@ void infint_mult2(infint_t *ii1, infint_t *ii2) {
free(acc);
}
void infint_shr(infint_t *ii) {
while(ii->next) ii = ii->next;
uint64_t lsb;
uint64_t msb = 0;
do {
lsb = ii->data & 1;
ii->data >>= 1;
ii->data += msb;
msb = lsb << 63;
} while (ii->prev);
}
uint64_t infint_div(infint_t *ii, uint64_t n) {
uint64_t tmp;
if (!ii->next) {
tmp = ii->data % n;
ii->data /= n;
}
else {
infint_t *i128, *ni, *ni_tmp;
while (ii->next) ii = ii->next;
i128 = infint_from_uint64(0);
ni = infint_from_uint64(n);
tmp = ii->data % n;
ii->data /= n;
do {
infint_push(i128, tmp);
ii = ii->prev;
i128->data = ii->data % n;
ii->data /= n;
while (infint_lt2(ni,i128)) {
infint_destroy(ni_tmp);
ni_tmp = infint_clone(ni);
infint_mult(ni,2);
}
infint_destroy(ni);
ni = ni_tmp;
tmp = 0;
while(!(ni->data & 1)) {
tmp += 1;
infint_sub2(i128,ni);
while(infint_lt2(ni,i128) & !(ni->data & 1)) {
infint_shr(ni);
tmp <<= 1;
}
}
ii->data += tmp;
tmp = n - i128->data;
} while (ii->prev);
}
while (ii->next) ii = ii->next;
while (ii->data == 0 && ii->prev) {
ii = ii->prev;
free(ii->next);
ii->next = NULL;
}
return tmp;
}
char infint_lt(infint_t *ii, uint64_t n) {
return !(ii->next) || ii->data < n;
return !(ii->next) && ii->data < n;
}
char infint_lt2(infint_t *ii1, infint_t *ii2) {

2
infint.h

@ -26,6 +26,8 @@ char infint_sub(infint_t *ii, uint64_t n);
char infint_sub2(infint_t *ii1, infint_t *ii2);
void infint_mult(infint_t *ii, uint64_t n);
void infint_mult2(infint_t *ii1, infint_t *ii2);
void infint_shr(infint_t *ii);
uint64_t infint_div(infint_t *ii, uint64_t n);
char infint_lt(infint_t *ii, uint64_t n);
char infint_lt2(infint_t *ii1, infint_t *ii2);

5
main.c

@ -25,6 +25,11 @@ int main() {
infint_print(test1);
printf("\n");
printf("test4 = test2 / 0x100000 = ");
uint64_t rem = infint_div(test2, 0x100000);
infint_print(test2);
printf(" R %ld\n", rem);
infint_destroy(test1);
infint_destroy(test2);
}

Loading…
Cancel
Save