bitwise-copy-bit-field, fxcopy-bit-field - copy a bitfield from one integer onto
another
(import (rnrs)) ;R6RS
(import (rnrs arithmetic bitwise)) ;R6RS
(import (rnrs arithmetic fixnums)) ;R6RS
(bitwise-copy-bit-field to start end from)
(fxcopy-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).
The following are reference implementations from R6RS.
; bitwise-copy-bit-field
(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))
; fxcopy-bit-field
(let* ((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))
Returns a single value; an exact integer. The fixnum variant returns a fixnum.
(fxcopy-bit-field #b0000001 2 5 #b1111000)
=> 1
(fxcopy-bit-field #b0000001 2 5 #b0001111)
=> 29
(fxcopy-bit-field #b0001111 2 5 #b0001111)
=> 31
This procedure is unique to R6RS.
This procedure can raise exceptions with the following condition types:
- &assertion (R6RS)
- The wrong number of arguments was passed or an argument was outside its
domain. In particular, start and end must be non-negative,
and start must be less than or equal to end.
- The fixnum variant furthermore requires that all arguments are fixnums and
that start and end are less than
(fixnum-width).
These procedures first appeared in R6RS. There is a similar procedure in SRFI-60
that uses a different argument order, copy-bit-field.