aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/data.c b/src/data.c
index 1d9222e75a7..a338dadfb69 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3290,14 +3290,29 @@ In this case, the sign bit is duplicated. */)
3290Lisp_Object 3290Lisp_Object
3291expt_integer (Lisp_Object x, Lisp_Object y) 3291expt_integer (Lisp_Object x, Lisp_Object y)
3292{ 3292{
3293 /* Special cases for -1 <= x <= 1, which never overflow. */
3294 if (EQ (x, make_fixnum (1)))
3295 return x;
3296 if (EQ (x, make_fixnum (0)))
3297 return EQ (x, y) ? make_fixnum (1) : x;
3298 if (EQ (x, make_fixnum (-1)))
3299 return ((FIXNUMP (y) ? XFIXNUM (y) & 1 : mpz_odd_p (*xbignum_val (y)))
3300 ? x : make_fixnum (1));
3301
3293 unsigned long exp; 3302 unsigned long exp;
3294 if (TYPE_RANGED_FIXNUMP (unsigned long, y)) 3303 if (FIXNUMP (y))
3295 exp = XFIXNUM (y); 3304 {
3296 else if (MOST_POSITIVE_FIXNUM < ULONG_MAX && BIGNUMP (y) 3305 if (ULONG_MAX < XFIXNUM (y))
3297 && mpz_fits_ulong_p (*xbignum_val (y))) 3306 overflow_error ();
3298 exp = mpz_get_ui (*xbignum_val (y)); 3307 exp = XFIXNUM (y);
3308 }
3299 else 3309 else
3300 overflow_error (); 3310 {
3311 if (ULONG_MAX <= MOST_POSITIVE_FIXNUM
3312 || !mpz_fits_ulong_p (*xbignum_val (y)))
3313 overflow_error ();
3314 exp = mpz_get_ui (*xbignum_val (y));
3315 }
3301 3316
3302 emacs_mpz_pow_ui (mpz[0], *bignum_integer (&mpz[0], x), exp); 3317 emacs_mpz_pow_ui (mpz[0], *bignum_integer (&mpz[0], x), exp);
3303 return make_integer_mpz (); 3318 return make_integer_mpz ();