Next: , Previous: Primitive Numerics, Up: Numbers

##### 5.5.2.14 Bitwise Operations

For the following bitwise functions, negative numbers are treated as infinite precision twos-complements. For instance -6 is bits ...111010, with infinitely many ones on the left. It can be seen that adding 6 (binary 110) to such a bit pattern gives all zeros.

— Scheme Procedure: logand n1 n2 ...
— C Function: scm_logand (n1, n2)

Return the bitwise and of the integer arguments.

```          (logand) ⇒ -1
(logand 7) ⇒ 7
(logand #b111 #b011 #b001) ⇒ 1
```
— Scheme Procedure: logior n1 n2 ...
— C Function: scm_logior (n1, n2)

Return the bitwise or of the integer arguments.

```          (logior) ⇒ 0
(logior 7) ⇒ 7
(logior #b000 #b001 #b011) ⇒ 3
```
— Scheme Procedure: logxor n1 n2 ...
— C Function: scm_loxor (n1, n2)

Return the bitwise xor of the integer arguments. A bit is set in the result if it is set in an odd number of arguments.

```          (logxor) ⇒ 0
(logxor 7) ⇒ 7
(logxor #b000 #b001 #b011) ⇒ 2
(logxor #b000 #b001 #b011 #b011) ⇒ 1
```
— Scheme Procedure: lognot n
— C Function: scm_lognot (n)

Return the integer which is the ones-complement of the integer argument, ie. each 0 bit is changed to 1 and each 1 bit to 0.

```          (number->string (lognot #b10000000) 2)
⇒ "-10000001"
(number->string (lognot #b0) 2)
⇒ "-1"
```
— Scheme Procedure: logtest j k
— C Function: scm_logtest (j, k)

Test whether j and k have any 1 bits in common. This is equivalent to `(not (zero? (logand j k)))`, but without actually calculating the `logand`, just testing for non-zero.

```          (logtest #b0100 #b1011) ⇒ #f
(logtest #b0100 #b0111) ⇒ #t
```
— Scheme Procedure: logbit? index j
— C Function: scm_logbit_p (index, j)

Test whether bit number index in j is set. index starts from 0 for the least significant bit.

```          (logbit? 0 #b1101) ⇒ #t
(logbit? 1 #b1101) ⇒ #f
(logbit? 2 #b1101) ⇒ #t
(logbit? 3 #b1101) ⇒ #t
(logbit? 4 #b1101) ⇒ #f
```
— Scheme Procedure: ash n cnt
— C Function: scm_ash (n, cnt)

Return n shifted left by cnt bits, or shifted right if cnt is negative. This is an “arithmetic” shift.

This is effectively a multiplication by 2^cnt, and when cnt is negative it's a division, rounded towards negative infinity. (Note that this is not the same rounding as `quotient` does.)

With n viewed as an infinite precision twos complement, `ash` means a left shift introducing zero bits, or a right shift dropping bits.

```          (number->string (ash #b1 3) 2)     ⇒ "1000"
(number->string (ash #b1010 -1) 2) ⇒ "101"

;; -23 is bits ...11101001, -6 is bits ...111010
(ash -23 -2) ⇒ -6
```
— Scheme Procedure: logcount n
— C Function: scm_logcount (n)

Return the number of bits in integer n. If n is positive, the 1-bits in its binary representation are counted. If negative, the 0-bits in its two's-complement binary representation are counted. If zero, 0 is returned.

```          (logcount #b10101010)
⇒ 4
(logcount 0)
⇒ 0
(logcount -2)
⇒ 1
```
— Scheme Procedure: integer-length n
— C Function: scm_integer_length (n)

Return the number of bits necessary to represent n.

For positive n this is how many bits to the most significant one bit. For negative n it's how many bits to the most significant zero bit in twos complement form.

```          (integer-length #b10101010) ⇒ 8
(integer-length #b1111)     ⇒ 4
(integer-length 0)          ⇒ 0
(integer-length -1)         ⇒ 0
(integer-length -256)       ⇒ 8
(integer-length -257)       ⇒ 9
```
— Scheme Procedure: integer-expt n k
— C Function: scm_integer_expt (n, k)

Return n raised to the power k. k must be an exact integer, n can be any number.

Negative k is supported, and results in 1/n^abs(k) in the usual way. n^0 is 1, as usual, and that includes 0^0 is 1.

```          (integer-expt 2 5)   ⇒ 32
(integer-expt -3 3)  ⇒ -27
(integer-expt 5 -3)  ⇒ 1/125
(integer-expt 0 0)   ⇒ 1
```
— Scheme Procedure: bit-extract n start end
— C Function: scm_bit_extract (n, start, end)

Return the integer composed of the start (inclusive) through end (exclusive) bits of n. The startth bit becomes the 0-th bit in the result.

```          (number->string (bit-extract #b1101101010 0 4) 2)
⇒ "1010"
(number->string (bit-extract #b1101101010 4 9) 2)
⇒ "10110"
```