commit 6ef22cc59aadd05ccb75df7d5dc097b26608fc76
parent f4a846b7af7d9d9e1bb8875b5ca1a3127125da4f
Author: Andres Navarro <canavarro82@gmail.com>
Date: Tue, 12 Apr 2011 01:55:25 -0300
Changed all of kinteger to use the IMath library.
Diffstat:
5 files changed, 49 insertions(+), 41 deletions(-)
diff --git a/src/Makefile b/src/Makefile
@@ -54,7 +54,7 @@ ksymbol.o: ksymbol.c ksymbol.h kobject.h kpair.h kstring.h kstate.h kmem.h \
kread.o: kread.c kread.h kobject.h ktoken.h kpair.h kstate.h kerror.h klisp.h \
kport.h
kwrite.o: kwrite.c kwrite.h kobject.h kpair.h kstring.h kstate.h kerror.h \
- klisp.h kport.h
+ klisp.h kport.h kinteger.h
kstate.o: kstate.c kstate.h klisp.h kobject.h kmem.h kstring.h klisp.h \
kground.h kenvironment.h kpair.h keval.h koperative.h kground.h \
krepl.h kcontinuation.h kapplicative.h kport.h ksymbol.h kport.h \
diff --git a/src/kinteger.c b/src/kinteger.c
@@ -46,7 +46,6 @@ TValue kbigint_copy(klisp_State *K, TValue src)
TValue copy = kbigint_new(K, false, 0);
Bigint *src_bigint = tv2bigint(src);
Bigint *copy_bigint = tv2bigint(copy);
- /* TODO: when the klisp allocator is used mem errors throw exceptions */
UNUSED(mp_int_init_copy(copy_bigint, src_bigint));
return copy;
}
@@ -57,104 +56,113 @@ TValue kbigint_copy(klisp_State *K, TValue src)
void kbigint_add_digit(klisp_State *K, TValue tv_bigint, int32_t base,
int32_t digit)
{
- /* XXX / TODO */
- return;
+ UNUSED(K);
+ Bigint *bigint = tv2bigint(tv_bigint);
+ UNUSED(mp_int_mul_value(bigint, base, bigint));
+ UNUSED(mp_int_add_value(bigint, digit, bigint));
}
/* This is used by the writer to get the digits of a number
tv_bigint must be positive */
int32_t kbigint_remove_digit(klisp_State *K, TValue tv_bigint, int32_t base)
{
- /* XXX / TODO */
- return 0;
+ UNUSED(K);
+ Bigint *bigint = tv2bigint(tv_bigint);
+ int32_t r;
+ UNUSED(mp_int_div_value(bigint, base, bigint, &r));
+ return r;
}
/* This is used by write to test if there is any digit left to print */
bool kbigint_has_digits(klisp_State *K, TValue tv_bigint)
{
UNUSED(K);
- /* XXX / TODO */
- return false;
+ Bigint *bigint = tv2bigint(tv_bigint);
+ return (mp_int_compare_zero(bigint) != 0);
}
/* Mutate the bigint to have the opposite sign, used in read,
write and abs */
-void kbigint_invert_sign(TValue tv_bigint)
+void kbigint_invert_sign(klisp_State *K, TValue tv_bigint)
{
- /* XXX / TODO */
- return;
+ UNUSED(K);
+ Bigint *bigint = tv2bigint(tv_bigint);
+ UNUSED(mp_int_neg(bigint, bigint));
}
/* this is used by write to estimate the number of chars necessary to
print the number */
int32_t kbigint_print_size(TValue tv_bigint, int32_t base)
{
- /* XXX / TODO */
- return 0;
+ Bigint *bigint = tv2bigint(tv_bigint);
+ return mp_int_string_len(bigint, base);
}
bool kbigint_eqp(TValue tv_bigint1, TValue tv_bigint2)
{
- /* XXX / TODO */
- return false;
+ Bigint *bigint1 = tv2bigint(tv_bigint1);
+ Bigint *bigint2 = tv2bigint(tv_bigint2);
+ return (mp_int_compare(bigint1, bigint2) == 0);
}
bool kbigint_ltp(TValue tv_bigint1, TValue tv_bigint2)
{
- /* XXX / TODO */
- return false;
+ Bigint *bigint1 = tv2bigint(tv_bigint1);
+ Bigint *bigint2 = tv2bigint(tv_bigint2);
+ return (mp_int_compare(bigint1, bigint2) < 0);
}
bool kbigint_lep(TValue tv_bigint1, TValue tv_bigint2)
{
- /* a <= b == !(a > b) == !(b < a) */
- return !kbigint_ltp(tv_bigint2, tv_bigint1);
+ Bigint *bigint1 = tv2bigint(tv_bigint1);
+ Bigint *bigint2 = tv2bigint(tv_bigint2);
+ return (mp_int_compare(bigint1, bigint2) <= 0);
}
bool kbigint_gtp(TValue tv_bigint1, TValue tv_bigint2)
{
- /* a > b == (b < a) */
- return kbigint_ltp(tv_bigint2, tv_bigint1);
+ Bigint *bigint1 = tv2bigint(tv_bigint1);
+ Bigint *bigint2 = tv2bigint(tv_bigint2);
+ return (mp_int_compare(bigint1, bigint2) > 0);
}
bool kbigint_gep(TValue tv_bigint1, TValue tv_bigint2)
{
- /* a >= b == !(a < b) */
- return !kbigint_ltp(tv_bigint1, tv_bigint2);
+ Bigint *bigint1 = tv2bigint(tv_bigint1);
+ Bigint *bigint2 = tv2bigint(tv_bigint2);
+ return (mp_int_compare(bigint1, bigint2) >= 0);
}
bool kbigint_negativep(TValue tv_bigint)
{
- /* XXX / TODO */
- return false;
+ Bigint *bigint = tv2bigint(tv_bigint);
+ return (mp_int_compare_zero(bigint) < 0);
}
-/* unlike the positive? applicative this would return true on zero,
- but zero is never represented as a bigint so there is no problem */
-/* Bigints constructed from fixints could be, but we don't care about
- zero returning positive in other place than in positive? */
bool kbigint_positivep(TValue tv_bigint)
{
- /* XXX / TODO */
- return false;
+ Bigint *bigint = tv2bigint(tv_bigint);
+ return (mp_int_compare_zero(bigint) > 0);
}
bool kbigint_oddp(TValue tv_bigint)
{
- /* XXX / TODO */
- return false;
+ Bigint *bigint = tv2bigint(tv_bigint);
+ return mp_int_is_odd(bigint);
}
bool kbigint_evenp(TValue tv_bigint)
{
- /* XXX / TODO */
- return false;
+ Bigint *bigint = tv2bigint(tv_bigint);
+ return mp_int_is_even(bigint);
}
TValue kbigint_abs(klisp_State *K, TValue tv_bigint)
{
- /* XXX / TODO */
UNUSED(K);
- return tv_bigint;
+ Bigint *src_bigint = tv2bigint(tv_bigint);
+ TValue copy = kbigint_new(K, false, 0);
+ Bigint *copy_bigint = tv2bigint(copy);
+ UNUSED(mp_int_abs(copy_bigint, src_bigint));
+ return copy;
}
-
diff --git a/src/kinteger.h b/src/kinteger.h
@@ -79,7 +79,7 @@ bool kbigint_evenp(TValue tv_bigint);
TValue kbigint_abs(klisp_State *K, TValue tv_bigint);
/* Mutate the bigint to have the opposite sign, used in read & write */
-void kbigint_invert_sign(TValue tv_bigint);
+void kbigint_invert_sign(klisp_State *K, TValue tv_bigint);
/* this is used by write to estimate the number of chars necessary to
print the number */
diff --git a/src/ktoken.c b/src/ktoken.c
@@ -399,7 +399,7 @@ TValue ktok_read_number(klisp_State *K, bool is_pos)
return i2tv(fixint);
} else {
if (!is_pos)
- kbigint_invert_sign(bigint_res);
+ kbigint_invert_sign(K, bigint_res);
return bigint_res;
}
}
diff --git a/src/kwrite.c b/src/kwrite.c
@@ -50,7 +50,7 @@ void kw_print_bigint(klisp_State *K, TValue bigint)
TValue copy = kbigint_copy(K, bigint);
/* must work with positive bigint to get the digits */
if (kbigint_negativep(bigint))
- kbigint_invert_sign(copy);
+ kbigint_invert_sign(K, copy);
while(kbigint_has_digits(K, copy)) {
int32_t digit = kbigint_remove_digit(K, copy, 10);