klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 3eb33dadbbb851936590ce7a9d7f2a51ba6b62bd
parent 986e75653f1c68b688dbc604a9c1a2fd40e20872
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Sat, 30 Apr 2011 23:22:41 -0300

First exact_to_inexact approx.

Diffstat:
Msrc/kreal.c | 45+++++++++++++++++++++++++++++++++++++++------
1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/src/kreal.c b/src/kreal.c @@ -19,16 +19,49 @@ #include "kmem.h" #include "kgc.h" +/* MAYBE move to kobject.h */ +#define ktag_double(d_) \ + ({ double d__ = d_; \ + TValue res; \ + if (isnan(d__)) res = KRWNPV; \ + else if (isinf(d__)) res = (d__ == INFINITY)? KIPINF : KIMINF; \ + else res = d2tv(d__); \ + res;}) + + + +double kbigint_to_double(Bigint *bigint) +{ + double radix = (double) UINT32_MAX + 1.0; + uint32_t ndigits = bigint->used - 1; + double accum = 0; + + /* bigint is in little endian format, but we traverse in + big endian */ + while(ndigits >= 0) { + accum = accum * radix + (double) bigint->digits[ndigits]; + --ndigits; + } +} + TValue kexact_to_inexact(klisp_State *K, TValue n) { switch(ttype(n)) { case K_TFIXINT: - case K_TBIGINT: - case K_TBIGRAT: - case K_TEINF: - /* TODO */ + return d2tv((double) ivalue(n)); + case K_TBIGINT: { + double d = kbigint_to_double(tv2bigint(n)); + /* d may be inf, ktag_double will handle it */ + /* MAYBE should throw an exception if strict is on */ + return ktag_double(d); + } + case K_TBIGRAT: { klisp_assert(0); - /* all of these are already inexact */ + return KUNDEF; + } + case K_TEINF: + return tv_equal(n, KEPINF)? KIPINF : KIMINF; + /* all of these are already inexact */ case K_TDOUBLE: case K_TIINF: case K_TRWNPV: @@ -36,6 +69,6 @@ TValue kexact_to_inexact(klisp_State *K, TValue n) return n; default: klisp_assert(0); - return KINERT; + return KUNDEF; } }