This chapter describes Scheme’s libraries for more specialized numerical operations: fixnum and flonum arithmetic, as well as bitwise operations on exact integers.
Every implementation must define its fixnum range as a closed interval
such that w is a (mathematical) integer w ≥ 24. Every mathematical integer within an implementation’s fixnum range must correspond to an exact integer that is representable within the implementation. A fixnum is an exact integer whose value lies within this fixnum range.
This section describes the (rnrs arithmetic fx (6))library, which defines various operations on fixnums. Fixnum operations perform integer arithmetic on their fixnum arguments, but raise an exception with condition type &implementation-restriction if the result is not a fixnum.
This section uses fx, fx1, fx2, etc., as parameter names for arguments that must be fixnums.
Returns #t if obj is an exact integer within the fixnum range, #f otherwise.
These procedures return w, - 2w-1 and 2w-1 - 1: the width, minimum and the maximum value of the fixnum range, respectively.
These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, #f otherwise.
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 is zero, greater than zero, less than zero, odd, or even.
These procedures return the maximum or minimum of their arguments.
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.
Rationale: These procedures are restricted to two arguments because their generalizations to three or more arguments would require precision proportional to the number of arguments.
With two arguments, this procedure returns the difference of its arguments, provided that difference is a fixnum.
With one argument, this procedure returns the additive inverse of its argument, provided that integer is a fixnum.
An exception with condition type &assertion is raised if the mathematically correct result of this procedure is not a fixnum.
(fx- (least-fixnum))
Fx2 must be nonzero. These procedures implement number-theoretic integer division and return the results of the corresponding mathematical operations specified in report section on “Integer division”.
(fxdiv fx1 fx2) ⇒ fx1 div fx2
Returns the two fixnum results of the following computation:
(let* ((s (+ fx1 fx2 fx3))
Returns the two fixnum results of the following computation:
(let* ((d (- fx1 fx2 fx3))
Returns the two fixnum results of the following computation:
(let* ((s (+ (* fx1 fx2) fx3))
Returns the unique fixnum that is congruent mod 2w to the one’s-complement of fx.
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.
Returns the fixnum result of the following computation:
(fxior (fxand fx1 fx2)
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)))
Returns the fixnum result of the following computation:
(do ((result 0 (+ result 1))
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.
(fxfirst-bit-set 0) ⇒ -1
Fx2 must be non-negative and less than (fixnum-width). The fxbit-set? procedure returns the fixnum result of the following computation:
(not
Fx2 must be non-negative and less than (fixnum-width). Fx3 must be 0 or 1. The fxcopy-bit procedure returns the result of the following computation:
(let* ((mask (fxarithmetic-shift-left 1 fx2)))
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 fixnum result of the following computation:
(let* ((mask (fxnot
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 fixnum result of the following computation:
(let* ((to fx1)
The absolute value of fx2 must be less than (fixnum-width). If
(* fx1 (expt 2 fx2))is a fixnum, then that fixnum is returned. Otherwise an exception with condition type &implementation-restriction is raised.
Fx2 must be non-negative. fxarithmetic-shift-left behaves the same as fxarithmetic-shift, and (fxarithmetic-shift-right fx1 fx2) behaves the same as (fxarithmetic-shift fx1 (fixnum- fx2)).
Fx2, fx3, and fx4 must be non-negative and less than (fixnum-width). Fx4 must be less than the difference between fx3 and fx3. The fxrotate-bit-field procedure returns the result of the following computation:
(let* ((n fx1)
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 bit field specified by fx2 and fx3.
(fxreverse-bit-field #b1010010 1 4)
This section describes the (rnrs arithmetic flonum (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.
Returns #t if obj is a flonum, #f otherwise.
Returns the best flonum representation of x.
The value returned is a flonum that is numerically closest to the argument.
Rationale: Not all reals are inexact, and some inexact reals may not be flonums.
Note: If flonums are represented in binary floating point, then implementations are strongly encouraged to break ties by preferring the floating point representation whose least significant bit is zero.
These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, #f otherwise. These predicates are required to be transitive.
(fl= +inf.0 +inf.0) ⇒ #t
These numerical predicates test a flonum for a particular property, returning #t or #f. The flinteger? procedure tests whether the number 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.
(flnegative? -0.0) ⇒ #f
Note: (flnegative? -0.0) must return #f, else it would lose the correspondence with (fl< -0.0 0.0), which is #f according to the IEEE standards.
These procedures return the maximum or minimum of their arguments.
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. (For implementations that represent flonums as IEEE binary floating point numbers, the meaning of “best” is defined by the IEEE standards.)
(fl+ +inf.0 -inf.0) ⇒ +nan.0
With two or more arguments, these procedures return the flonum difference or quotient of their flonum arguments, associating to the left. With one argument, however, they return the additive or multiplicative flonum inverse of their argument. In general, they should return the flonum that best approximates the mathematical difference or quotient. (For implementations that represent flonums as IEEE binary floating point numbers, the meaning of “best” is reasonably well-defined by the IEEE standards.)
(fl- +inf.0 +inf.0) ⇒ +nan.0
For undefined quotients, fl/ behaves as specified by the IEEE standards:
(fl/ 1.0 0.0) ⇒ +inf.0
Returns the absolute value of fl.
These procedures implement number-theoretic integer division and return the results of the corresponding mathematical operations specified in report section on “Integer division”. For zero divisors, these procedures may return a NaN or some meaningless flonum.
(fldiv fl1 fl2) ⇒ fl1 div fl2
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.
(flnumerator +inf.0) ⇒ +inf.0The following behavior is strongly recommended but not required:
(flnumerator -0.0) ⇒ -0.0
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 is halfway between two integers.
Rationale: The flround procedure rounds to even for consistency with the default rounding mode specified by the IEEE floating point standard.
Although infinities and NaNs are not integers, these procedures return an infinity when given an infinity as an argument, and a NaN when given a NaN:
(flfloor +inf.0) ⇒ +inf.0
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 fl (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.
See report section on “Transcendental functions” for the underlying mathematical operations. In the event that these operations do not yield a real result for the given arguments, the result may be a NaN, or may be some meaningless flonum.
Implementations that use IEEE binary floating point arithmetic are encouraged to follow the relevant standards for these procedures.
(flexp +inf.0) ⇒ +inf.0
Returns the principal square root of fl. For - 0.0, flsqrt should return - 0.0; for other negative arguments, the result may be a NaN or some meaningless flonum.
Rationale: The behavior of flsqrt on - 0.0 is consistent with the IEEE floating point standard.
(flsqrt +inf.0) ⇒ +inf.0
Returns fl1 raised to the power fl2. fl1 should be non-negative; if fl1 is negative, then the result may be a NaN, or may be some meaningless flonum. If fl1 is zero, then the result is zero. For positive mathitfl1,
These condition types could be defined by the following code:
(define-condition-type &no-infinities
These types describe that a program has executed an arithmetic operations that is specified to return an infinity or a NaN, respectively, on a Scheme implementation that is not able to represent the infinity or NaN. (See report section on “Representability of infinities and NaNs”.)
Returns a flonum that is numerically closest to fx.
Note: The result of this procedure may not be numerically equal to fx, because the fixnum precision may be greater than the flonum precision.
This section describes the (rnrs arithmetic bitwise (6))library. The exact bitwise arithmetic provides generic operations on exact integers. This section uses ei, ei1, ei2, etc., as parameter names that must be exact integers.
Some procedures allow extracting bit fields, i.e., numbers representing subsequences of the binary representation of an exact integer. Bit fields are always positive, and always defined using a finite number of bits, contrary to 2’s complement representation which implicitly uses an infinite extension of 0 bits or 1 bits to the left.
Returns the exact integer whose two’s complement representation is the one’s complement of the two’s complement representation of ei.
These procedures return the exact integer 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 (either - 1 or 0) that acts as identity for the operation.
Returns the exact integer that is the result of the following computation:
(bitwise-ior (bitwise-and ei1 ei2)
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)))
Returns the exact integer that is the result of the following computation:
(do ((result 0 (+ result 1))
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.
(bitwise-first-bit-set 0) ⇒ -1
Ei2 must be non-negative. Returns the result of the following computation:
(not (zero?
Ei2 must be non-negative, and ei3 must be either 0 or 1. The bitwise-copy-bit procedure returns the result of the following computation:
(let* ((mask (bitwise-arithmetic-shift-left 1 ei2)))
Ei2 and ei3 must be non-negative, and ei2 must be less than or equal to ei3. This procedure returns the result of the following computation:
(let* ((mask
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 the following computation:
(let* ((to ei1)
Returns the result of the following computation:
(floor (* ei1 (expt 2 ei2)))Examples:
(bitwise-arithmetic-shift -6 -1)
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, ei3, ei4 must be non-negative, ei2 must be less than or equal to ei3, and ei4 must be non-negative. The procedure returns the result of the following computation:
(let* ((n ei1)
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 bit field specified by ei2 and ei3.
(bitwise-reverse-bit-field #b1010010 1 4)