[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Merging bignum to master
From: |
Andy Moreton |
Subject: |
Re: Merging bignum to master |
Date: |
Tue, 14 Aug 2018 01:21:51 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1.50 (windows-nt) |
On Sun 12 Aug 2018, Tom Tromey wrote:
>>>>>> "Basil" == Basil L Contovounesios <address@hidden> writes:
>
> Basil> It'd be nice if expt could be updated to handle bignums:
>
> What do you think of this?
>
> Tom
>
> diff --git a/src/floatfns.c b/src/floatfns.c
> index bbf7df4db3..c55418a35c 100644
> --- a/src/floatfns.c
> +++ b/src/floatfns.c
> @@ -206,25 +206,28 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
> {
> CHECK_FIXNUM_OR_FLOAT (arg1);
> CHECK_FIXNUM_OR_FLOAT (arg2);
> - if (FIXNUMP (arg1) /* common lisp spec */
> + if (INTEGERP (arg1) /* common lisp spec */
> && FIXNUMP (arg2) /* don't promote, if both are ints, and */
> && XFIXNUM (arg2) >= 0) /* we are sure the result is not fractional */
> { /* this can be improved by
> pre-calculating */
> - EMACS_INT y; /* some binary powers of x then accumulating */
> - EMACS_UINT acc, x; /* Unsigned so that overflow is well defined. */
You have dropped some of the commentary that explains how it is trying
to give similar behaviour to Common Lisp. See the description at:
<http://www.lispworks.com/documentation/lw50/CLHS/Body/f_exp_e.htm>
> Lisp_Object val;
> + mpz_t x, *xp, r;
>
> - x = XFIXNUM (arg1);
> - y = XFIXNUM (arg2);
> - acc = (y & 1 ? x : 1);
> -
> - while ((y >>= 1) != 0)
> + if (BIGNUMP (arg1))
> + xp = &XBIGNUM (arg1)->value;
> + else
> {
> - x *= x;
> - if (y & 1)
> - acc *= x;
> + mpz_init_set_si (x, XFIXNUM (arg1));
This doesn't work for systems where sizeof (EMACS_INT) > sizeof (long).
> + xp = &x;
> }
> - XSETINT (val, acc);
> +
> + mpz_init (r);
> + mpz_pow_ui (r, *xp, XFIXNUM (arg2));
Likewise.
> +
> + val = make_number (r);
> + mpz_clear (r);
> + if (xp == &x)
> + mpz_clear (x);
> return val;
> }
> return make_float (pow (XFLOATINT (arg1), XFLOATINT (arg2)));
> diff --git a/test/src/floatfns-tests.el b/test/src/floatfns-tests.el
> index 7714c05d60..4fab032ecb 100644
> --- a/test/src/floatfns-tests.el
> +++ b/test/src/floatfns-tests.el
> @@ -46,4 +46,8 @@
> (should (= (+ (logb most-positive-fixnum) 1)
> (logb (+ most-positive-fixnum 1)))))
>
> +(ert-deftest bignum-expt ()
> + (should (= (expt 10 100)
> + (apply #'* (make-list 100 10)))))
> +
> (provide 'floatfns-tests)
Re: Merging bignum to master, Ulrich Mueller, 2018/08/12