Merge pull request #476 from tramboi/expt_neg

(expt bignum -k) was equal to (expt bignum k)
This commit is contained in:
Alex Shinn 2018-06-10 22:39:07 +08:00 committed by GitHub
commit e8c10ce259
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 3 deletions

View file

@ -610,14 +610,21 @@ sexp sexp_bignum_remainder (sexp ctx, sexp a, sexp b) {
} }
sexp sexp_bignum_expt (sexp ctx, sexp a, sexp b) { sexp sexp_bignum_expt (sexp ctx, sexp a, sexp b) {
sexp_sint_t e = sexp_unbox_fx_abs(b); sexp_sint_t e = sexp_unbox_fixnum(b);
sexp_sint_t abs_e;
if (e < 0)
abs_e = -e;
else
abs_e = e;
sexp_gc_var2(res, acc); sexp_gc_var2(res, acc);
sexp_gc_preserve2(ctx, res, acc); sexp_gc_preserve2(ctx, res, acc);
res = sexp_fixnum_to_bignum(ctx, SEXP_ONE); res = sexp_fixnum_to_bignum(ctx, SEXP_ONE);
acc = sexp_copy_bignum(ctx, NULL, a, 0); acc = sexp_copy_bignum(ctx, NULL, a, 0);
for (; e; e>>=1, acc=sexp_bignum_mul(ctx, NULL, acc, acc)) for (; abs_e; abs_e>>=1, acc=sexp_bignum_mul(ctx, NULL, acc, acc))
if (e & 1) if (abs_e & 1)
res = sexp_bignum_mul(ctx, NULL, res, acc); res = sexp_bignum_mul(ctx, NULL, res, acc);
if (e < 0)
res = sexp_div(ctx, sexp_fixnum_to_bignum(ctx, SEXP_ONE), res);
sexp_gc_release2(ctx); sexp_gc_release2(ctx);
return sexp_bignum_normalize(res); return sexp_bignum_normalize(res);
} }

View file

@ -16,6 +16,10 @@
(define (run-tests) (define (run-tests)
(test-begin "numbers") (test-begin "numbers")
(test 3 (expt 3 1))
;(test 1/3 (expt 3 -1))
(test 1/300000000000000000000 (expt 300000000000000000000 -1))
(test '(536870912 536870913 536870911 -536870912 -536870911 -536870913) (test '(536870912 536870913 536870911 -536870912 -536870911 -536870913)
(integer-neighborhoods (expt 2 29))) (integer-neighborhoods (expt 2 29)))