Next: , Previous: , Up: stdlib arithmetic   [Index]


5.11.2 Fixnums

Every implementation must define its fixnum range as a closed interval: [-2^{(w-1)}, 2^{(w-1)}-1] such that w is a (mathematical) integer w >= 24. Every mathematical integer within an implementation’s fixnum range must correspond to an exact integer object that is representable within the implementation. A fixnum is an exact integer object whose value lies within this fixnum range.

This section describes the (rnrs arithmetic fixnums (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 names for arguments that must be fixnums.

Procedure: fixnum? obj

Return #t if obj is an exact integer object within the fixnum range, #f otherwise.

Procedure: fixnum-width
Procedure: least-fixnum
Procedure: greatest-fixnum

These procedures return w, -2^{(w-1)} and 2^{(w-1)} - 1: the width, minimum and the maximum value of the fixnum range, respectively.

Procedure: fx=? fx1 fx2 fx3
Procedure: fx>? fx1 fx2 fx3
Procedure: fx<? fx1 fx2 fx3
Procedure: fx>=? fx1 fx2 fx3
Procedure: fx<=? fx1 fx2 fx3

These procedures return #t if their arguments are (respectively): equal, monotonically increasing, monotonically decreasing, monotonically nondecreasing, or monotonically nonincreasing, #f otherwise.

Procedure: fxzero? fx
Procedure: fxpositive? fx
Procedure: fxnegative? fx
Procedure: fxodd? fx
Procedure: fxeven? fx

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.

Procedure: fxmax fx1 fx2
Procedure: fxmin fx1 fx2

These procedures return the maximum or minimum of their arguments.

Procedure: fx+ fx1 fx2
Procedure: fx* fx1 fx2

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.

Procedure: fx- fx1 fx2
Procedure: fx- fx

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.

(fx- (least-fixnum))  ⇒ exception &assertion
Procedure: fxdiv-and-mod fx1 fx2
Procedure: fxdiv fx1 fx2
Procedure: fxmod fx1 fx2
Procedure: fxdiv0-and-mod0 fx1 fx2
Procedure: fxdiv0 fx1 fx2
Procedure: fxmod0 fx1 fx2

fx2 must be nonzero.

These procedures implement number–theoretic integer division and return the results of the corresponding mathematical operations specified in Integer division

(fxdiv fx1 fx2)         ⇒ fx1 div fx2
(fxmod fx1 fx2)         ⇒ fx1 mod fx2
(fxdiv-and-mod fx1 fx2) ⇒ fx1 div fx2, fx1 mod fx2
                                        ; two return values
(fxdiv0 fx1 fx2)        ⇒ fx1 div_0 fx2
(fxmod0 fx1 fx2)        ⇒ fx1 mod_0 fx2
(fxdiv0-and-mod0 fx1 fx2)
⇒ fx1 fx1 div_0 fx2, fx1 mod_0 fx2
   ; two return values
Procedure: fx+/carry fx1 fx2 fx3

Return 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))
Procedure: fx-/carry fx1 fx2 fx3

Return 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))
Procedure: fx*/carry fx1 fx2 fx3

Return 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))
Procedure: fxnot fx

Return the unique fixnum that is congruent mod 2^w to the one’s–complement of fx.

Procedure: fxand fx1
Procedure: fxior fx1
Procedure: fxxor fx1

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.

Procedure: fxif fx1 fx2 fx3

Return 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))
Procedure: fxbit-count fx

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)))
Procedure: fxlength fx

Return 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))
Procedure: fxfirst-bit-set fx

Return 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
(fxfirst-bit-set 1)        ⇒  0
(fxfirst-bit-set -4)       ⇒  2
Procedure: fxbit-set? fx1 fx2

fx2 must be non–negative.

The fxbit-set? procedure returns #t if the fx2th bit is 1 in the two’s complement representation of fx1, and #f otherwise. This is the fixnum result of the following computation:

(if (fx>= fx2 (fx- (fixnum-width) 1))
    (fxnegative? fx1)
    (not
      (fxzero?
         (fxand fx1
                (fxarithmetic-shift-left 1 fx2)))))
Procedure: fxcopy-bit fx1 fx2 fx3

fx2 must be non–negative and less than w-1. Fx3 must be 0 or 1.

The fxcopy-bit procedure returns the result of replacing the fx2th 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))
Procedure: fxbit-field fx1 fx2 fx3

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))
Procedure: fxcopy-bit-field fx1 fx2 fx3 fx4

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 bits in fx4 from position 0 (inclusive) to position fx3-fx2 (exclusive), 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))
       (mask3 (fxnot (fxarithmetic-shift-left -1 (- end start)))))
  (fxif mask
        (fxarithmetic-shift-left (fxand from mask3)
                                 start)
        to))
Procedure: fxarithmetic-shift fx1 fx2

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.

Procedure: fxarithmetic-shift-left fx1 fx2
Procedure: fxarithmetic-shift-right fx1 fx2

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)).

Procedure: fxrotate-bit-field fx1 fx2 fx3 fx4

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 or equal to 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)))
  (fxcopy-bit-field n start end
    (fxior
      (fxarithmetic-shift-left
        (fxbit-field n start (fx- end count)) count)
      (fxarithmetic-shift-right
        (fxbit-field n start end) (fx- width count)))))
Procedure: fxreverse-bit-field fx1 fx2 fx3

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).

(fxreverse-bit-field #b1010010 1 4)       ⇒  88 ; #b1011000

Next: , Previous: , Up: stdlib arithmetic   [Index]