[plt-scheme] Major math screwiness going on with fractions!
Hi everyone,
I was tracking down a problem in a program I was running involving numeric
comparisons. I've isolated it down to this:
###############
dyoo at dyoo-desktop:~$ mzscheme
Welcome to MzScheme v369.6 [3m], Copyright (c) 2004-2007 PLT Scheme Inc.
> (< 1 (/ 1 4))
#t
###############
After recovering from laughter, I looked at it further. This bug appears
to affect both mzscheme and mzschemecgc. It's not a JIT problem:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dyoo at dyoo-desktop:~/local/plt-svn/src/mzscheme$ PLTNOMZJIT=1 mzscheme
Welcome to MzScheme v369.6 [3m], Copyright (c) 2004-2007 PLT Scheme Inc.
> (< 1 (/ 1 4))
#t
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
It appears to have to do with rationals: if I convert down to inexacts,
things work out as expected.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> (< 1 (exact->inexact (/ 1 4)))
#f
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
It's in the logic of rational_lt in src/mzscheme/rational.c; some of the
fast-path logic looks very suspicious to me, but I haven't put my finger
on it yet. If I comment out the fast case logic, the bug's fixed, so I
know there's some something funky going on in the block here:
/* Avoid multiplication in simple cases: */
if (scheme_bin_lt_eq(ra->num, rb->num)
&& scheme_bin_gt_eq(ra->num, rb->num)) {
if (!or_eq) {
if (scheme_rational_eq(a, b))
return 0;
}
return 1;
} else if (or_eq) {
if (scheme_rational_eq(a, b))
return 1;
}
I've commented it out in my own repository. I have to go grab dinner
right now, but hopefully someone can fix this? It looks like it got
introduced yesterday or so in r5455.
Anyway, hope this helps!