aboutsummaryrefslogtreecommitdiffstats
path: root/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/src/data.c b/src/data.c
index ac74ff5547f..8a2d600b30d 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3298,18 +3298,37 @@ ash_lsh_impl (Lisp_Object value, Lisp_Object count, bool lsh)
3298 3298
3299 Lisp_Object val; 3299 Lisp_Object val;
3300 3300
3301 CHECK_FIXNUM (value); 3301 CHECK_INTEGER (value);
3302 CHECK_FIXNUM (count); 3302 CHECK_FIXNUM (count);
3303 3303
3304 if (XINT (count) >= EMACS_INT_WIDTH) 3304 if (BIGNUMP (value))
3305 XSETINT (val, 0); 3305 {
3306 else if (XINT (count) > 0) 3306 mpz_t result;
3307 XSETINT (val, XUINT (value) << XINT (count)); 3307 mpz_init (result);
3308 else if (XINT (count) <= -EMACS_INT_WIDTH) 3308 if (XINT (count) >= 0)
3309 XSETINT (val, lsh ? 0 : XINT (value) < 0 ? -1 : 0); 3309 mpz_mul_2exp (result, XBIGNUM (value)->value, XINT (count));
3310 else
3311 mpz_tdiv_q_2exp (result, XBIGNUM (value)->value, - XINT (count));
3312 val = make_number (result);
3313 mpz_clear (result);
3314 }
3310 else 3315 else
3311 XSETINT (val, (lsh ? XUINT (value) >> -XINT (count) 3316 {
3312 : XINT (value) >> -XINT (count))); 3317 /* Just do the work as bignums to make the code simpler. */
3318 mpz_t result;
3319 eassume (FIXNUMP (value));
3320 if (lsh)
3321 mpz_init_set_ui (result, XUINT (value));
3322 else
3323 mpz_init_set_si (result, XINT (value));
3324 if (XINT (count) >= 0)
3325 mpz_mul_2exp (result, result, XINT (count));
3326 else
3327 mpz_tdiv_q_2exp (result, result, - XINT (count));
3328 val = make_number (result);
3329 mpz_clear (result);
3330 }
3331
3313 return val; 3332 return val;
3314} 3333}
3315 3334