aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTom Tromey2018-07-08 09:22:17 -0600
committerTom Tromey2018-07-12 22:12:28 -0600
commit27980e36040d0693fe997de6b6b73c09c3ce1cb5 (patch)
tree15e8f67ea21970bad9d4956f105dd41047a20894 /src
parentcca0e79ea81712786f92a6668c61001e60d24f32 (diff)
downloademacs-27980e36040d0693fe997de6b6b73c09c3ce1cb5.tar.gz
emacs-27980e36040d0693fe997de6b6b73c09c3ce1cb5.zip
Make ash and lsh handle bignums
* src/data.c (ash_lsh_impl): Handle bignums. * test/src/data-tests.el (data-tests-ash-lsh): New test.
Diffstat (limited to 'src')
-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