mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-05 03:20:39 -08:00
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.
This commit is contained in:
parent
d247e1d30a
commit
8136df6a8c
3 changed files with 13 additions and 4 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue