## 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 i 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 i 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`

Returns 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-arithmetic-shift-left replacement-bit bitno)
i))
```

Procedure: `bitwise-bit-field` `n` `start` `end`

Returns 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))
(bitwise-not
(bitwise-arithmetic-shift-left -1 end)))
(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))`.

If `i` is a primitive integer type, then `amount` must be less than the number of bits in the promoted type of `i` (32 or 64). If the type is unsigned, an unsigned (logic) shift is done for `bitwise-arithmetic-shift-right`, rather than a signed (arithmetic) shift.

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.

### SRFI-60 Logical Number Operations

Kawa supports SRFI-60 “Integers as Bits” as well, although we generally recommend using the R6RS-compatible functions instead when possible. Unless noted as being a builtin function, to use these you must first `(require 'srfi-60)` or `(import (srfi :60))` (or `(import (srfi :60 integer-bits))`).

Procedure: `logand` `i` `...`

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

Procedure: `logior` `i` `...`

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

Procedure: `logxor` `i` `...`

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

Procedure: `lognot` `i`

Equivalent to `(bitwise-not i)`. Builtin.

Procedure: `bitwise-merge` `mask` `i` `j`

Equivalent to `(bitwise-if mask i j)`.

Procedure: `any-bits-set?` `i` `j`

Equivalent to `(logtest i j)`.

Procedure: `logcount` `i`

Procedure: `bit-count` `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. Builtin as `logcount`.

Procedure: `integer-length` `i`

Equivalent to `(bitwise-length i)`. Builtin.

Procedure: `log2-binary-factors` `i`

Procedure: `first-set-bit` `i`

Equivalent to `(bitwise-first-bit-set i)`.

Procedure: `logbit?` `pos` `i`

Procedure: `bit-set?` `pos` `i`

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

Procedure: `copy-bit` `bitno` `i` `bool`

Equivalent to `(bitwise-copy-bit i bitno (if bool 1 0))`.

Procedure: `bit-field` `n` `start` `end`

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

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

Equivalent to `(bitwise-copy-bit-field to start end from)`.

Procedure: `arithmetic-shift` `i` `j`

Equivalent to `(bitwise-arithmetic-shift i j)`. Builtin.

Procedure: `ash` `i` `j`

Alias for `arithmetic-shift`. Builtin.

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

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

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

Equivalent to `(bitwise-reverse-bit-field i start end)`.

Procedure: `integer->list` `k` [`length`]

Procedure: `list->integer` `list`

The `integer->list` procedure returns a list of `length` booleans corresponding to the bits of the non-negative integer `k`, with `#t` for `1` and `#f` for `0`. `length` defaults to `(bitwise-length k)`. The list will be in order from MSB to LSB, with the value of `(odd? k)` in the last car.

The `list->integer` procedure returns the integer corresponding to the booleans in the list `list`. The `integer->list` and `list->integer` procedures are inverses so far as `equal?` is concerned.

Procedure: `booleans->integer` `bool1` `...`

Returns the integer coded by the `bool1` ... arguments. Equivalent to `(list->integer (list bool1 ...))`.

### Deprecated Logical Number Operations

This older function is still available, but we recommend using the R6RS-compatible function.

Procedure: `bit-extract` `n` `start` `end`

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