1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-17 09:10:22 +02:00

Add 'round-ash', a rounding arithmetic shift operator

* libguile/numbers.c (left_shift_exact_integer,
  floor_right_shift_exact_integer, round_right_shift_exact_integer): New
  static functions.

  (scm_round_ash): New procedure.

  (scm_ash): Reimplement in terms of 'left_shift_exact_integer' and
  'floor_right_shift_exact_integer'.

* libguile/numbers.h: Add prototype for scm_round_ash.  Rename the
  second argument of 'scm_ash' from 'cnt' to 'count'.

* test-suite/tests/numbers.test (round-ash, ash): Add new unified
  testing framework for 'ash' and 'round-ash'.  Previously, the tests
  for 'ash' were not very comprehensive; for example, they did not
  include a single test where the number to be shifted was a bignum.

* doc/ref/api-data.texi (Bitwise Operations): Add documentation for
  'round-ash'.  Improve documentation for `ash'.
This commit is contained in:
Mark H Weaver 2013-03-03 04:35:09 -05:00
parent a285b18ca8
commit e08a12b535
4 changed files with 234 additions and 153 deletions

View file

@ -1686,19 +1686,15 @@ starts from 0 for the least significant bit.
@end lisp
@end deffn
@deffn {Scheme Procedure} ash n cnt
@deffnx {C Function} scm_ash (n, cnt)
Return @var{n} shifted left by @var{cnt} bits, or shifted right if
@var{cnt} is negative. This is an ``arithmetic'' shift.
@deffn {Scheme Procedure} ash n count
@deffnx {C Function} scm_ash (n, count)
Return @math{floor(@var{n} * 2^@var{count})}.
@var{n} and @var{count} must be exact integers.
This is effectively a multiplication by @m{2^{cnt}, 2^@var{cnt}}, and
when @var{cnt} is negative it's a division, rounded towards negative
infinity. (Note that this is not the same rounding as @code{quotient}
does.)
With @var{n} viewed as an infinite precision twos complement,
@code{ash} means a left shift introducing zero bits, or a right shift
dropping bits.
With @var{n} viewed as an infinite-precision twos-complement
integer, @code{ash} means a left shift introducing zero bits
when @var{count} is positive, or a right shift dropping bits
when @var{count} is negative. This is an ``arithmetic'' shift.
@lisp
(number->string (ash #b1 3) 2) @result{} "1000"
@ -1709,6 +1705,28 @@ dropping bits.
@end lisp
@end deffn
@deffn {Scheme Procedure} round-ash n count
@deffnx {C Function} scm_round_ash (n, count)
Return @math{round(@var{n} * 2^@var{count})}.
@var{n} and @var{count} must be exact integers.
With @var{n} viewed as an infinite-precision twos-complement
integer, @code{round-ash} means a left shift introducing zero
bits when @var{count} is positive, or a right shift rounding
to the nearest integer (with ties going to the nearest even
integer) when @var{count} is negative. This is a rounded
``arithmetic'' shift.
@lisp
(number->string (round-ash #b1 3) 2) @result{} \"1000\"
(number->string (round-ash #b1010 -1) 2) @result{} \"101\"
(number->string (round-ash #b1010 -2) 2) @result{} \"10\"
(number->string (round-ash #b1011 -2) 2) @result{} \"11\"
(number->string (round-ash #b1101 -2) 2) @result{} \"11\"
(number->string (round-ash #b1110 -2) 2) @result{} \"100\"
@end lisp
@end deffn
@deffn {Scheme Procedure} logcount n
@deffnx {C Function} scm_logcount (n)
Return the number of bits in integer @var{n}. If @var{n} is