From a770fb44288c75fa2b0471ceaf00bf741376e40f Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Sat, 7 Jul 2018 14:22:44 -0600 Subject: [PATCH] Make logcount handle bignums * src/data.c (Flogcount): Handle bignums. * test/src/data-tests.el (data-tests-logcount): New test. --- src/data.c | 17 ++++++++++++++++- test/src/data-tests.el | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/data.c b/src/data.c index c9504694e37..2e366b5313f 100644 --- a/src/data.c +++ b/src/data.c @@ -3184,7 +3184,22 @@ of VALUE. If VALUE is negative, return the number of zero bits in the representation. */) (Lisp_Object value) { - CHECK_FIXNUM (value); + CHECK_INTEGER (value); + + if (BIGNUMP (value)) + { + if (mpz_cmp_si (XBIGNUM (value)->value, 0) >= 0) + return make_fixnum (mpz_popcount (XBIGNUM (value)->value)); + mpz_t tem; + mpz_init (tem); + mpz_neg (tem, XBIGNUM (value)->value); + mpz_sub_ui (tem, tem, 1); + Lisp_Object result = make_fixnum (mpz_popcount (tem)); + mpz_clear (tem); + return result; + } + + eassume (FIXNUMP (value)); EMACS_INT v = XINT (value) < 0 ? -1 - XINT (value) : XINT (value); return make_fixnum (EMACS_UINT_WIDTH <= UINT_WIDTH ? count_one_bits (v) diff --git a/test/src/data-tests.el b/test/src/data-tests.el index dd6ce196f96..561b7bd9ca6 100644 --- a/test/src/data-tests.el +++ b/test/src/data-tests.el @@ -587,4 +587,7 @@ comparing the subr with a much slower lisp implementation." (should (< (1- most-negative-fixnum) most-negative-fixnum)) (should (fixnump (1- (1+ most-positive-fixnum))))) +(ert-deftest data-tests-logcount () + (should (= (logcount (read "#xffffffffffffffffffffffffffffffff")) 128))) + ;;; data-tests.el ends here -- 2.39.2