summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2018-07-07 14:22:44 -0600
committerTom Tromey <tom@tromey.com>2018-07-12 22:12:27 -0600
commita770fb44288c75fa2b0471ceaf00bf741376e40f (patch)
tree263136cf11b50104797d7642247b87fab2814ded /src
parentc7e393bc4130c871a92fef7e9ac0c7c1832aa614 (diff)
downloademacs-a770fb44288c75fa2b0471ceaf00bf741376e40f.tar.gz
Make logcount handle bignums
* src/data.c (Flogcount): Handle bignums. * test/src/data-tests.el (data-tests-logcount): New test.
Diffstat (limited to 'src')
-rw-r--r--src/data.c17
1 files changed, 16 insertions, 1 deletions
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)