Logical Number Operations

These functions operate on the 2’s complement binary representation of an exact integer.

Procedure: bitwise-not i

Returns the bit-wise logical inverse of the argument. More formally, returns the exact integer whose two’s complement representation is the one’s complement of the two’s complement representation of i.

Procedure: bitwise-and i ...

Procedure: bitwise-ior i ...

Procedure: bitwise-xor i ...

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 that acts as identity for the operation: -1, 0, or 0, respectively.

Procedure: bitwise-if i1 i2 i3

Returns the exact integer that is the bit-wise “if” of the twos complement representations of its arguments, i.e. for each bit, if it is 1 in i1, the corresponding bit in i2 becomes the value of the corresponding bit in the result, and if it is 0, the corresponding bit in i3 becomes the corresponding bit in the value of the result. This is equivaent to the following computation:

(bitwise-ior (bitwise-and i1 i2)
             (bitwise-and (bitwise-not i1) i3))

Procedure: bitwise-bit-count i

If ei is non-negative, returns the number of 1 bits in the twos complement representation of i. Otherwise it returns the result of the following computation:

(bitwise-not (bitwise-bit-count (bitwise-not i)))

Procedure: bitwise-length i

Returns the number of bits needed to represent i if it is positive, and the number of bits needed to represent (bitwise-not i) if it is negative, which is the exact integer that is the result of the following computation:

(do ((result 0 (+ result 1))
     (bits (if (negative? i)
               (bitwise-not i)
               ei)
           (bitwise-arithmetic-shift bits -1)))
    ((zero? bits)
     result))

This is the number of bits needed to represent i in an unsigned field.

Procedure: bitwise-first-bit-set i

Returns the index of the least significant 1 bit in the twos complement representation of i. If ei is 0, then - 1 is returned.

(bitwise-first-bit-set 0) ⇒ -1
(bitwise-first-bit-set 1) ⇒ 0
(bitwise-first-bit-set -4) ⇒ 2

Procedure: bitwise-bit-set? i1 i2

Returns #t if the i2’th bit (where i2 must be non-negative) is 1 in the two’s complement representation of i1, and #f otherwise. This is the result of the following computation:

(not (zero?
       (bitwise-and
         (bitwise-arithmetic-shift-left 1 i2)
         i1)))

Procedure: bitwise-copy-bit i bitno replacement-bit

Return the result of replacing the bitno’th bit of i by replacement-bit, where bitno must be non-negative, and replacement-bit must be either 0 or 1. This is the result of the following computation:

(let* ((mask (bitwise-arithmetic-shift-left 1 bitno)))
  (bitwise-if mask
            (bitwise-arithmetic-shift-left replacement-bit bitno)
            i))

Procedure: bitwise-bit-field n start end

Return the integer formed from the (unsigned) bit-field starting at start and ending just before end. Same as:

(let ((mask
       (bitwise-not
        (bitwise-arithmetic-shift-left -1 end))))
  (bitwise-arithmetic-shift-right
    (bitwise-and n mask)
    start))

Procedure: bitwise-copy-bit-field to start end from

Returns the result of replacing in to the bits at positions from start (inclusive) to end (exclusive) by the bits in from from position 0 (inclusive) to position end - start (exclusive). Both start and start must be non-negative, and start must be less than or equal to start.

This is the result of the following computation:

(let* ((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))

Procedure: bitwise-arithmetic-shift i j

Shifts i by j. It is a “left” shift if j>0, and a “right” shift if j<0. The result is equal to (floor (* i (expt 2 j))).

Examples:

(bitwise-arithmetic-shift -6 -1) ⇒-3
(bitwise-arithmetic-shift -5 -1) ⇒ -3
(bitwise-arithmetic-shift -4 -1) ⇒ -2
(bitwise-arithmetic-shift -3 -1) ⇒ -2
(bitwise-arithmetic-shift -2 -1) ⇒ -1
(bitwise-arithmetic-shift -1 -1) ⇒ -1

Procedure: bitwise-arithmetic-shift-left i amount

Procedure: bitwise-arithmetic-shift-right i amount

The amount must be non-negative The bitwise-arithmetic-shift-left procedure returns the same result as bitwise-arithmetic-shift, and (bitwise-arithmetic-shift-right i amount) returns the same result as (bitwise-arithmetic-shift i (- amount));

Procedure: bitwise-rotate-bit-field n start end count

Returns the result of cyclically permuting in n the bits at positions from start (inclusive) to end (exclusive) by count bits towards the more significant bits, start and end must be non-negative, and start must be less than or equal to end. This is the result of the following computation:

(let* ((n     ei1)
       (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))

Procedure: bitwise-reverse-bit-field i start end

Returns the result obtained from i by reversing the order of the bits at positions from start (inclusive) to end (exclusive), where start and end must be non-negative, and start must be less than or equal to end.

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

Procedure: logop op x y

Perform one of the 16 bitwise operations of x and y, depending on op.

Procedure: logtest i j

Returns true if the arguments have any bits in common. Same as (not (zero? (bitwise-and i j))), but is more efficient.

Deprecated Logical Number Operations

These older functions are still available, but we recommand using the R6RS-compatible functions.

Procedure: lognot i

Equivalent to (bitwise-not i).

Procedure: logand i ...

Equivalent to (bitwise-and i ...).

Procedure: logior i ...

Equivalent to (bitwise-ior i ...).

Procedure: logxor i ...

Equivalent to (bitwise-xor i ...).

Procedure: logcount i

Count the number of 1-bits in i, if it is non-negative. If i is negative, count number of 0-bits. Same as (bitwise-bit-count i) if i is non-negative.

Procedure: integer-length i

Equivalent to (bitwise-length i).

Procedure: logbit? i pos

Equivalent to bitwise-bit-set? i pos).

Procedure: arithmetic-shift i j

Equivalent to bitwise-arithmetic-shift i j).

Procedure: ash i j

Alias for arithmetic-shift.

Procedure: bit-extract n start end

Equivalent to (bitwise-bit-field n start end).