aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Tromey2018-07-08 09:22:17 -0600
committerTom Tromey2018-07-12 22:12:28 -0600
commit27980e36040d0693fe997de6b6b73c09c3ce1cb5 (patch)
tree15e8f67ea21970bad9d4956f105dd41047a20894
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.
-rw-r--r--src/data.c37
-rw-r--r--test/src/data-tests.el6
2 files changed, 34 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
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index 2423d7a7098..07159df48cf 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -614,4 +614,10 @@ comparing the subr with a much slower lisp implementation."
614 (data-tests-check-sign (% -1 -3) (% nb1 nb3)) 614 (data-tests-check-sign (% -1 -3) (% nb1 nb3))
615 (data-tests-check-sign (mod -1 -3) (mod nb1 nb3)))) 615 (data-tests-check-sign (mod -1 -3) (mod nb1 nb3))))
616 616
617(ert-deftest data-tests-ash-lsh ()
618 (should (= (ash most-negative-fixnum 1)
619 (* most-negative-fixnum 2)))
620 (should (= (lsh most-negative-fixnum 1)
621 (* (abs most-negative-fixnum) 2))))
622
617;;; data-tests.el ends here 623;;; data-tests.el ends here