Discovered with Aubrey Jaffer's r4rstest.scm, expt isn't returning exact results in cases where it can; here's a patch:
@@ -3131,15 +3153,17 @@
case OP_EXPT:
x=car(sc->args);
- if(cdr(sc->args)==sc->NIL) {
- Error_0(sc,"expt: needs two arguments");
- } else {
- pointer y=cadr(sc->args);
- /* This 'if' is an R5RS compatability fix. */
- if (rvalue(x) == 0 && rvalue(y) < 0)
- s_return(sc, mk_real(sc, 0));
- s_return(sc, mk_real(sc, pow(rvalue(x),rvalue(y))));
- }
+ pointer y=cadr(sc->args);
+ /* This 'if' is an R5RS compatability fix. */
+ if (rvalue(x) == 0 && rvalue(y) < 0)
+ s_return(sc, mk_real(sc, 0));
+ double rex = pow(rvalue(x),rvalue(y));
+ /* r5rs requires an exact result when both args exact
+ we also check that the result fits in an integer */
+ long iex = (long )rex;
+ if (num_is_integer(x) && num_is_integer(y) && rex == (double )iex)
+ s_return(sc, mk_integer(sc, iex));
+ s_return(sc, mk_real(sc, rex));
case OP_FLOOR:
x=car(sc->args);
A fix for this issue was committed as revision 81 that was based in part on the suggested change.