This section describes Scheme's libraries for more specialized numerical operations: fixnum and flonum arithmetic, as well as bitwise operations on exact integer objects.
A number of procedures operate on the binary two's-complement representations of exact integer objects: Bit positions within an exact integer object are counted from the right, i.e. bit 0 is the least significant bit. Some procedures allow extracting bit fields, i.e., number objects representing subsequences of the binary representation of an exact integer object. Bit fields are always positive, and always defined using a finite number of bits.
On Sagittarius Scheme, fixnum is 30 bits or 62 bits depending on platform. On 32 bits platform it fixnum is 30 bits, and 64 bits platform it is 62 bits. However, non 32 bits platform is not well tested so if you find a bug please send a report.
This section uses fx, fx1 fx2, etc., as parameter names for arguments that must be fixnums.
[R6RS] Returns #t if obj is an exact integer object within the fixnum range, #f otherwise.
[R6RS] These procedures returns bit size of fixnum, minimum and maximum value of the fixnum range, respectively.
[R6RS] These procedures return #t if their arguments are: equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, #f otherwise.
[R6RS] These numerical predicates test a fixnum for a particular property, returning #t or #f. The five properties tested by these procedures are: whether the number object is zero, greater than zero, less than zero, odd, or even.
[R6RS] These procedures return the maximum or minimum of their arguments.
[R6RS] These procedures return the sum or product of their arguments,
provided that sum or product is a fixnum. An exception with condition type
&implementation-restriction
is raised if that sum or product is not a
fixnum.
[R6RS] With two arguments, this procedure returns the difference fx1- fx2, provided that difference is a fixnum.
With one argument, this procedure returns the additive inverse of its argument, provided that integer object is a fixnum.
An exception with condition type &implementation-restriction
is raised if
the mathematically correct result of this procedure is not a fixnum.
NOTE: R6RS says it raises &assertion
if the result is not fixnum, however
Sagittarius raises &implementation-restriction
for consistency with
fx+
and fx*
.
[R6RS] Fx2 must be nonzero. These procedures implement number-theoretic
integer division and return the results of the corresponding mathematical operations
specified in
(rnrs base (6))
section.
[R6RS] Returns the two fixnum results of the following computation:
(let* ((s (+ _fx1_ _fx2_ _fx3_))
(s0 (mod0 s (expt 2 (fixnum-width))))
(s1 (div0 s (expt 2 (fixnum-width)))))
(values s0 s1))
[R6RS] Returns the two fixnum results of the following computation:
(let* ((d (- _fx1_ _fx2_ _fx3_))
(d0 (mod0 d (expt 2 (fixnum-width))))
(d1 (div0 d (expt 2 (fixnum-width)))))
(values d0 d1))
[R6RS] Returns the two fixnum results of the following computation:
(let* ((s (+ (* _fx1_ _fx2_) _fx3_))
(s0 (mod0 s (expt 2 (fixnum-width))))
(s1 (div0 s (expt 2 (fixnum-width)))))
(values s0 s1))
[R6RS] Returns bitwise not of fixnum fx.
[R6RS] These procedures return the fixnum that is the bit-wise "and", "inclusive or", or "exclusive or" of the two's complement representations of their arguments. If they are passed only one argument, they return that argument. If they are passed no arguments, they return the fixnum (either - 1 or 0) that acts as identity for the operation.
[R6RS] Returns the fixnum that is the bit-wise "if" of the two's complement representations of its arguments, i.e. for each bit, if it is 1 in fx1, the corresponding bit in fx2 becomes the value of the corresponding bit in the result, and if it is 0, the corresponding bit in fx3 becomes the corresponding bit in the value of the result. This is the fixnum result of the following computation:
(fxior (fxand _fx1_ _fx2_)
(fxand (fxnot _fx1_) _fx3_))
[R6RS] If fx is non-negative, this procedure returns the number of 1 bits in the two's complement representation of fx. Otherwise it returns the result of the following computation:
(fxnot (fxbit-count (fxnot _ei_)))
[R6RS] Returns the number of bits needed to represent fx if it is
positive, and the number of bits needed to represent (fxnot _fx_)
if
it is negative, which is the fixnum result of the following computation:
(do ((result 0 (+ result 1))
(bits (if (fxnegative? _fx_)
(fxnot _fx_)
_fx_)
(fxarithmetic-shift-right bits 1)))
((fxzero? bits)
result))
[R6RS] Returns the index of the least significant 1 bit in the two's complement representation of fx. If fx is 0, then - 1 is returned.
[R6RS] Fx2 must be non-negative and less than (fixnum-width)
.
The fxbit-set?
procedure returns #t if the _fx2_th bit is 1 in the
two's complement representation of fx1, and #f otherwise. This is the
fixnum result of the following computation:
(not
(fxzero?
(fxand _fx1_ (fxarithmetic-shift-left 1 _fx2_))))
[R6RS] Fx2 must be non-negative and less than (fixnum-width)
.
Fx3 must be 0 or 1. The fxcopy-bit
procedure returns the result of
replacing the _fx2_th bit of fx1 by fx3, which is the result of
the following computation:
(let* ((mask (fxarithmetic-shift-left 1 _fx2_)))
(fxif mask
(fxarithmetic-shift-left _fx3_ _fx2_)
_fx1_))
[R6RS] Fx2 and fx3 must be non-negative and less than
(fixnum-width)
. Moreover, fx2 must be less than or equal to
fx3. The fxbit-field
procedure returns the number represented by
the bits at the positions from fx2 (inclusive) to fx3 (exclusive),
which is the fixnum result of the following computation:
(let* ((mask (fxnot
(fxarithmetic-shift-left -1 _fx3_))))
(fxarithmetic-shift-right (fxand _fx1_ mask)
_fx2_))
[R6RS] Fx2 and fx3 must be non-negative and less than
(fixnum-width)
. Moreover, fx2 must be less than or equal to
fx3. The fxcopy-bit-field
procedure returns the result of replacing
in fx1 the bits at positions from fx2 (inclusive) to fx3(exclusive) by the corresponding bits in fx4, which is the fixnum result
of the following computation:
(let* ((to _fx1_)
(start _fx2_)
(end _fx3_)
(from _fx4_)
(mask1 (fxarithmetic-shift-left -1 start))
(mask2 (fxnot
(fxarithmetic-shift-left -1 end)))
(mask (fxand mask1 mask2)))
(fxif mask
(fxarithmetic-shift-left from start)
to))
[R6RS] The absolute value of fx2 must be less than
(fixnum-width)
. If
(floor (* _fx1_ (expt 2 _fx2_)))
is a fixnum, then that fixnum is returned. Otherwise an exception with condition
type &implementation-restriction
is raised.
[R6RS] Fx2 must be non-negative, and less than (fixnum-width)
.
The fxarithmetic-shift-left
procedure behaves the same as
fxarithmetic-shift
, and (fxarithmetic-shift-right _fx1_ _fx2_)
behaves the same as (fxarithmetic-shift _fx1_ (fx- _fx2_))
.
[R6RS] Fx2, fx3, and fx4 must be non-negative and less
than (fixnum-width)
. Fx2 must be less than or equal to fx3.
Fx4 must be less than the difference between fx3 and fx2. The
fxrotate-bit-field
procedure returns the result of cyclically permuting
in fx1 the bits at positions from fx2 (inclusive) to fx3(exclusive) by fx4 bits towards the more significant bits, which is the
result of the following computation:
(let* ((n _fx1_)
(start _fx2_)
(end _fx3_)
(count _fx4_)
(width (fx- end start)))
(if (fxpositive? width)
(let* ((count (fxmod count width))
(field0
(fxbit-field n start end))
(field1
(fxarithmetic-shift-left
field0 count))
(field2
(fxarithmetic-shift-right
field0 (fx- width count)))
(field (fxior field1 field2)))
(fxcopy-bit-field n start end field))
n))
[R6RS] Fx2 and fx3 must be non-negative and less than
(fixnum-width)
. Moreover, fx2 must be less than or equal to fx3.
The fxreverse-bit-field
procedure returns the fixnum obtained from
fx1 by reversing the order of the bits at positions from fx2(inclusive) to fx3 (exclusive).
This section describes the (rnrs arithmetic flonums (6))
library.
This section uses fl, fl1, fl2, etc., as parameter names for
arguments that must be flonums, and ifl as a name for arguments that must
be integer-valued flonums, i.e., flonums for which the integer-valued?
predicate returns true.
[R6RS] This library exports procedures for flonum operations.
[R6RS] Returns #t if obj is a flonum, #f otherwise.
[R6RS] These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, #f otherwise.
[R6RS] These numerical predicates test a flonum for a particular property,
returning #t or #f. The flinteger?
procedure tests whether the number
object is an integer, flzero?
tests whether it is fl=?
to zero,
flpositive?
tests whether it is greater than zero, flnegative?
tests whether it is less than zero
, flodd?
tests whether it is
odd, fleven?
tests whether it is even, flfinite?
tests whether
it is not an infinity and not a NaN, flinfinite?
tests whether it is
an infinity, and flnan?
tests whether it is a NaN.
[R6RS] These procedures return the maximum or minimum of their arguments. They always return a NaN when one or more of the arguments is a NaN.
[R6RS] These procedures return the flonum sum or product of their flonum arguments. In general, they should return the flonum that best approximates the mathematical sum or product.
[R6RS] Returns the absolute value of fl.
[R6RS] These procedures implement number-theoretic integer division and
return the results of the corresponding mathematical operations (see
(rnrs base (6))
. For zero divisors, these
procedures may return a NaN or some unspecified flonum.
[R6RS] These procedures return the numerator or denominator of fl as a flonum; the result is computed as if fl was represented as a fraction in lowest terms. The denominator is always positive. The denominator of 0.0 is defined to be 1.0.
[R6RS] These procedures return integral flonums for flonum arguments that
are not infinities or NaNs. For such arguments, flfloor
returns the largest
integral flonum not larger than fl. The flceiling
procedure returns
the smallest integral flonum not smaller than fl. The fltruncate
procedure returns the integral flonum closest to fl whose absolute value
is not larger than the absolute value of fl. The flround
procedure
returns the closest integral flonum to fl, rounding to even when _fl_represents a number halfway between two integers.
Although infinities and NaNs are not integer objects, these procedures return an infinity when given an infinity as an argument, and a NaN when given a NaN.
[R6RS] These procedures compute the usual transcendental functions. The flexp
procedure computes the base-e exponential of fl. The fllog
procedure
with a single argument computes the natural logarithm of fl1
(not the base
ten logarithm); (fllog _fl1_ _fl2_)
computes the base-_fl2_logarithm of fl1. The flasin
, flacos
, and flatan
procedures compute arcsine, arccosine, and arctangent, respectively.
(flatan _fl1_ _fl2_)
computes the arc tangent of fl1/fl2.
[R6RS] Returns the principal square root of fl. For - 0.0, flsqrt
returns 0.0; for other negative arguments, the result unspecified flonum.
[R6RS] Either fl1 should be non-negative, or, if fl1 is negative,
fl2 should be an integer object. The flexpt
procedure returns _fl1_raised to the power fl2. If fl1 is negative and fl2 is not an
integer object, the result is a NaN. If fl1 is zero, then the result is zero.
[R6RS] These types describe that a program has executed an arithmetic operations that is specified to return an infinity or a NaN, respectively.
Here is the hierarchy of these conditions.
+ &implementation-restriction (see ["Conditions"](#rnrs.conditions.6))
+ &no-infinities
+ &no-nans
[R6RS] Returns a flonum that is numerically closest to fx.
This section describes the (rnrs arithmetic bitwise (6))
library.
The exact bitwise arithmetic provides generic operations on exact integer
objects. This section uses ei, ei1, ei2, etc., as parameter
names that must be exact integer objects.
[R6RS] This library exports procedures for exact bitwise arithmetic operations.
[R6RS] Returns the exact integer object whose two's complement representation is the one's complement of the two's complement representation of ei.
[R6RS] These procedures return the exact integer object that is the bit-wise "and", "inclusive or", or "exclusive or" of the two's complement representations of their arguments. If they are passed only one argument, they return that argument. If they are passed no arguments, they return the integer object (either - 1 or 0) that acts as identity for the operation.
[R6RS] Returns the exact integer object that is the bit-wise "if" of the two's complement representations of its arguments, i.e. for each bit, if it is 1 in ei1, the corresponding bit in ei2 becomes the value of the corresponding bit in the result, and if it is 0, the corresponding bit in ei3 becomes the corresponding bit in the value of the result. This is the result of the following computation:
(bitwise-ior (bitwise-and _ei1_ _ei2_)
(bitwise-and (bitwise-not _ei1_) _ei3_))
[R6RS] If ei is non-negative, this procedure returns the number of 1 bits in the two's complement representation of ei. Otherwise it returns the result of the following computation:
(bitwise-not (bitwise-bit-count (bitwise-not _ei_)))
[R6RS] Returns the number of bits needed to represent ei if it is
positive, and the number of bits needed to represent
(bitwise-not _ei_)
if it is negative, which is the exact integer
object that is the result of the following computation:
(do ((result 0 (+ result 1))
(bits (if (negative? _ei_)
(bitwise-not _ei_)
_ei_)
(bitwise-arithmetic-shift bits -1)))
((zero? bits)
result))
[R6RS] Returns the index of the least significant 1 bit in the two's complement representation of ei. If ei is 0, then - 1 is returned.
[R6RS] Ei2 must be non-negative. The bitwise-bit-set?
procedure returns #t if the _ei2_th bit is 1 in the two's complement
representation of ei1, and #f otherwise. This is the result of the
following computation:
(not (zero?
(bitwise-and
(bitwise-arithmetic-shift-left 1 _ei2_)
_ei1_)))
[R6RS] Ei2 must be non-negative, and ei3 must be either 0
or 1. The bitwise-copy-bit
procedure returns the result of replacing the
_ei2_th bit of ei1 by the _ei2_th bit of ei3, which is the
result of the following computation:
(let* ((mask (bitwise-arithmetic-shift-left 1 _ei2_)))
(bitwise-if mask
(bitwise-arithmetic-shift-left _ei3_ _ei2_)
_ei1_))
[R6RS] Ei2 and ei3 must be non-negative, and ei2 must be
less than or equal to ei3. The bitwise-bit-field
procedure returns
he number represented by the bits at the positions from ei2 (inclusive) to
ei3 (exclusive), which is the result of the following computation:
(let ((mask
(bitwise-not
(bitwise-arithmetic-shift-left -1 _ei3_))))
(bitwise-arithmetic-shift-right
(bitwise-and _ei1_ mask)
_ei2_))
[R6RS] Ei2 and ei3 must be non-negative, and ei2 must
be less than or equal to ei3. The bitwise-copy-bit-field
procedure
returns the result of replacing in ei1 the bits at positions from
var{ei2} (inclusive) to ei3 (exclusive) by the corresponding bits in
ei4, which is the fixnum result of the following computation:
(let* ((to _ei1_)
(start _ei2_)
(end _ei3_)
(from _ei4_)
(mask1
(bitwise-arithmetic-shift-left -1 start))
(mask2
(bitwise-not
(bitwise-arithmetic-shift-left -1 end)))
(mask (bitwise-and mask1 mask2)))
(bitwise-if mask
(bitwise-arithmetic-shift-left from
start)
to))
[R6RS] Returns the result of the following computation:
(floor (* _ei1_ (expt 2 _ei2_)))
ei2 must be a fixnum. This is implementation restriction.
[R6RS] Ei2 must be non-negative. The
bitwise-arithmetic-shift-left
procedure returns the same result as
bitwise-arithmetic-shift
, and
(bitwise-arithmetic-shift-right _ei1_ _ei2_)
returns the same result as
(bitwise-arithmetic-shift _ei1_ (- _ei2_))
.
ei2 must be a fixnum. This is implementation restriction.
[R6RS] Ei2, ei3, ei4 must be non-negative, _ei2_must be less than or equal to ei3, and ei4 must be non-negative.
The bitwise-rotate-bit-field
procedure returns the result of cyclically
permuting in ei1 the bits at positions from ei2 (inclusive) to
ei3 (exclusive) by ei4 bits towards the more significant bits,
which is the result of the following computation:
(let* ((n _ei1_)
(start _ei2_)
(end _ei3_)
(count _ei4_)
(width (- end start)))
(if (positive? width)
(let* ((count (mod count width))
(field0
(bitwise-bit-field n start end))
(field1 (bitwise-arithmetic-shift-left
field0 count))
(field2 (bitwise-arithmetic-shift-right
field0
(- width count)))
(field (bitwise-ior field1 field2)))
(bitwise-copy-bit-field n start end field))
n))
ei4 must be a fixnum. This is implementation restriction.
[R6RS] Ei2 and ei3 must be non-negative, and ei2 must be
less than or equal to ei3. The bitwise-reverse-bit-field
procedure
returns the result obtained from ei1 by reversing the order of the bits at
positions from ei2 (inclusive) to ei3 (exclusive).