klisp

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

commit caf70fec181120b02c0107a94f55f9d09789afe1
parent 76b5100d7620d70420d5dc457182e0fc6b8d0537
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed, 19 Oct 2011 16:57:33 -0300

Bugfix: round only rounded correctly if decimal part was .5!!. Fixed to also round when decimal part was > .5. Found location of round bug, it's actually in dtoa (and was tripped by the $check operative when trying to put together the msg).

Diffstat:
Msrc/krational.c | 8+++++---
Msrc/kreal.c | 1+
Msrc/tests/numbers.k | 22+++++++++++++++-------
3 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/src/krational.c b/src/krational.c @@ -492,14 +492,16 @@ TValue kbigrat_to_integer(klisp_State *K, TValue tv_bigrat, kround_mode mode) if (mp_rat_compare_zero(n) < 0 && mp_int_compare_zero(rest) != 0) UNUSED(mp_int_sub_value(K, quot, 1, quot)); break; - case K_ROUND_EVEN: + case K_ROUND_EVEN: { UNUSED(mp_int_mul_pow2(K, rest, 1, rest)); - if (mp_int_compare(rest, MP_DENOM_P(n)) == 0 && - mp_int_is_odd(quot)) + int cmp = mp_int_compare(rest, MP_DENOM_P(n)); + if (cmp > 0 || (cmp == 0 && mp_int_is_odd(quot))) { UNUSED(mp_int_add_value(K, quot, mp_rat_compare_zero(n) < 0? -1 : 1, quot)); + } break; } + } krooted_tvs_pop(K); krooted_tvs_pop(K); diff --git a/src/kreal.c b/src/kreal.c @@ -731,6 +731,7 @@ TValue kdouble_to_integer(klisp_State *K, TValue tv_double, kround_mode mode) int res = fesetround(FE_TONEAREST); /* REFACTOR: should be done once only... */ klisp_assert(res == 0); d = nearbyint(d); + break; } } /* ASK John: we currently return inexact if given inexact is this ok? diff --git a/src/tests/numbers.k b/src/tests/numbers.k @@ -10,9 +10,13 @@ ;; Shutt for clarification (but I warn you that while he is very cooperative ;; with this kind of things he sometimes takes a while to answer). ;; -;; The round thing is obviously a bug, (round 1.1) doesn't hang so, -;; I'm inclined to think that it's related to some memory issue like the strict -;; arithmetic one. +;; The round thing is actually a bug in dtoa (kreal.c) the function that +;; converts doubles to strings and has nothing to do with rounding. +;; When the error msg was being generated the interpreter entered an infinite +;; loop in dtoa. +;; You can test this easily just entering 1.1 in the interpreter. +;; I'll have to work on this one. I'll have to reread the paper and work on it +;; with gdb. ;; ;; Andres Navarro ;; @@ -348,13 +352,17 @@ ($check equal? (round 0) 0) ($check equal? (round 1/2) 0) -;($check equal? (round 1.1) 1) ; FREEZES INTERPRETER +($check equal? (round #e1.1) 1) +($check =? (round 1.1) 1) ($check equal? (round 3/2) 2) -;--($check equal? (round 1.9) 2) +($check equal? (round #e1.9) 2) +($check =? (round 1.9) 2) ($check equal? (round -1/2) 0) -;-- ($check equal? (round -1.1) -1) ; FREEZES INTERPRETER +($check =? (round #e-1.1) -1) +($check equal? (round #e-1.1) -1) ($check equal? (round -3/2) -2) -;--($check equal? (round -1.9) -2) +($check equal? (round #e-1.9) -2) +($check =? (round -1.9) -2) ;; 12.8.5 rationalize simplest-rational