diff --git a/bignum.c b/bignum.c index 3052cbe3..37b2de8e 100644 --- a/bignum.c +++ b/bignum.c @@ -1347,7 +1347,7 @@ sexp sexp_sub (sexp ctx, sexp a, sexp b) { r = sexp_fx_sub(a, b); /* VM catches this case */ break; case SEXP_NUM_FIX_FLO: - r = sexp_make_flonum(ctx, sexp_fixnum_to_double(a)-sexp_flonum_value(b)); + r = sexp_make_flonum(ctx, a==SEXP_ZERO ? -sexp_flonum_value(b) : sexp_fixnum_to_double(a)-sexp_flonum_value(b)); break; case SEXP_NUM_FIX_BIG: tmp1 = sexp_fixnum_to_bignum(ctx, a); diff --git a/vm.c b/vm.c index cdb6ef9f..f97ed0c7 100644 --- a/vm.c +++ b/vm.c @@ -1717,9 +1717,9 @@ sexp sexp_apply (sexp ctx, sexp proc, sexp args) { else if (sexp_flonump(tmp1) && sexp_flonump(tmp2)) _ARG1 = sexp_fp_sub(ctx, tmp1, tmp2); else if (sexp_flonump(tmp1) && sexp_fixnump(tmp2)) - _ARG1 = sexp_make_flonum(ctx, sexp_flonum_value(tmp1) - (double)sexp_unbox_fixnum(tmp2)); + _ARG1 = sexp_make_flonum(ctx, sexp_flonum_value(tmp1) - sexp_fixnum_to_double(tmp2)); else if (sexp_fixnump(tmp1) && sexp_flonump(tmp2)) - _ARG1 = sexp_make_flonum(ctx, (double)sexp_unbox_fixnum(tmp1) - sexp_flonum_value(tmp2)); + _ARG1 = sexp_make_flonum(ctx, tmp1==SEXP_ZERO ? -sexp_flonum_value(tmp2) : sexp_fixnum_to_double(tmp1)-sexp_flonum_value(tmp2)); #endif else sexp_raise("-: not a number", sexp_list2(ctx, tmp1, tmp2)); #endif