[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: |
Thu, 16 Aug 2018 00:41:32 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/26.1.50 (windows-nt) |
On Tue 14 Aug 2018, Andy Moreton wrote:
> 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 and Basil, please try the following patch for expt.
I have given it some light sanity testing on Windows 64bit.
AndyM
diff --git a/src/floatfns.c b/src/floatfns.c
index bbf7df4db3..0e7e3090e8 100644
--- a/src/floatfns.c
+++ b/src/floatfns.c
@@ -204,29 +204,38 @@ DEFUN ("expt", Fexpt, Sexpt, 2, 2, 0,
doc: /* Return the exponential ARG1 ** ARG2. */)
(Lisp_Object arg1, Lisp_Object arg2)
{
- CHECK_FIXNUM_OR_FLOAT (arg1);
+ CHECK_NUMBER (arg1);
CHECK_FIXNUM_OR_FLOAT (arg2);
- if (FIXNUMP (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. */
- Lisp_Object val;
-
- x = XFIXNUM (arg1);
- y = XFIXNUM (arg2);
- acc = (y & 1 ? x : 1);
-
- while ((y >>= 1) != 0)
- {
- x *= x;
- if (y & 1)
- acc *= x;
- }
- XSETINT (val, acc);
- return val;
+
+ 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 */
+ && (sizeof (EMACS_INT) <= sizeof (long)
+ || (long) XFIXNUM (arg2) == XFIXNUM (arg2)))
+ {
+ Lisp_Object res;
+ mpz_t val;
+
+ mpz_init (val);
+ if (BIGNUMP (arg1))
+ {
+ mpz_pow_ui (val, XBIGNUM (arg1)->value, XFIXNUM (arg2));
+ }
+ else if (XFIXNUM (arg1) >= 0)
+ {
+ mpz_ui_pow_ui (val, XFIXNUM (arg1), XFIXNUM (arg2));
+ }
+ else
+ {
+ mpz_ui_pow_ui (val, -XFIXNUM (arg1), XFIXNUM (arg2));
+ if (XFIXNUM (arg2) & 1)
+ mpz_neg (val, val);
+ }
+ res = make_number (val);
+ mpz_clear (val);
+ return res;
}
+
return make_float (pow (XFLOATINT (arg1), XFLOATINT (arg2)));
}
Re: Merging bignum to master, Ulrich Mueller, 2018/08/12
- Re: Merging bignum to master, Paul Eggert, 2018/08/12
- Re: Merging bignum to master, Eli Zaretskii, 2018/08/12
- Re: Merging bignum to master, Paul Eggert, 2018/08/12
- Re: Merging bignum to master, Tom Tromey, 2018/08/12
- Re: Merging bignum to master, Andreas Schwab, 2018/08/13
- Re: Merging bignum to master, Ulrich Mueller, 2018/08/13