[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 8136df6: Make logcount act like CL on negative arg
From: |
Paul Eggert |
Subject: |
[Emacs-diffs] master 8136df6: Make logcount act like CL on negative arg |
Date: |
Sat, 30 Sep 2017 18:38:19 -0400 (EDT) |
branch: master
commit 8136df6a8cbf071266eb38f5baef005f4e9241a3
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>
Make logcount act like CL on negative arg
Behaving like Common Lisp is less likely to lead to surprises,
as it yields the same answers on 32- vs 64-bit machines.
* doc/lispref/numbers.texi (Bitwise Operations):
Document behavior on negative integers.
* src/data.c (Flogcount):
Behave like Common Lisp for negative arguments.
* test/src/data-tests.el (data-tests-popcnt)
(data-tests-logcount): Test negative args too.
---
doc/lispref/numbers.texi | 7 ++++++-
src/data.c | 6 ++++--
test/src/data-tests.el | 4 +++-
3 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/doc/lispref/numbers.texi b/doc/lispref/numbers.texi
index 5058063..be74b0c 100644
--- a/doc/lispref/numbers.texi
+++ b/doc/lispref/numbers.texi
@@ -1113,9 +1113,14 @@ bit is one in the result if, and only if, the @var{n}th
bit is zero in
@defun logcount integer
This function returns the @dfn{Hamming weight} of @var{integer}: the
number of ones in the binary representation of @var{integer}.
+If @var{integer} is negative, it returns the number of zero bits in
+its two's complement binary representation. The result is always
+nonnegative.
@example
-(logcount 42) ; 42 = #b101010
+(logcount 43) ; 43 = #b101011
+ @result{} 4
+(logcount -43) ; -43 = #b111...1010101
@result{} 3
@end example
@end defun
diff --git a/src/data.c b/src/data.c
index fd8cdd1..2e7f3e0 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3071,11 +3071,13 @@ usage: (logxor &rest INTS-OR-MARKERS) */)
DEFUN ("logcount", Flogcount, Slogcount, 1, 1, 0,
doc: /* Return population count of VALUE.
-If VALUE is negative, the count is of its two's complement representation. */)
+This is the number of one bits in the two's complement representation
+of VALUE. If VALUE is negative, return the number of zero bits in the
+representation. */)
(Lisp_Object value)
{
CHECK_NUMBER (value);
- EMACS_UINT v = XUINT (value);
+ EMACS_INT v = XINT (value) < 0 ? -1 - XINT (value) : XINT (value);
return make_number (EMACS_UINT_WIDTH <= UINT_WIDTH
? count_one_bits (v)
: EMACS_UINT_WIDTH <= ULONG_WIDTH
diff --git a/test/src/data-tests.el b/test/src/data-tests.el
index d1154cc..374d168 100644
--- a/test/src/data-tests.el
+++ b/test/src/data-tests.el
@@ -109,12 +109,14 @@
(defun data-tests-popcnt (byte)
"Calculate the Hamming weight of BYTE."
+ (if (< byte 0)
+ (setq byte (lognot byte)))
(setq byte (- byte (logand (lsh byte -1) #x55555555)))
(setq byte (+ (logand byte #x33333333) (logand (lsh byte -2) #x33333333)))
(lsh (* (logand (+ byte (lsh byte -4)) #x0f0f0f0f) #x01010101) -24))
(ert-deftest data-tests-logcount ()
- (should (cl-loop for n in (number-sequence 0 255)
+ (should (cl-loop for n in (number-sequence -255 255)
always (= (logcount n) (data-tests-popcnt n))))
;; https://oeis.org/A000120
(should (= 11 (logcount 9727)))
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master 8136df6: Make logcount act like CL on negative arg,
Paul Eggert <=