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:
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