mailto:srfi-60@srfi.schemers.org
.
See instructions
here to subscribe to the list. You can access previous messages via the
archive of the mailing list.
The discussions of the withdrawn SRFI-33: "Integer Bitwise-operation Library" seemed to founder on consistency of procedure names and arity; and on perceived competition with the boolean arrays of SRFI-47.
I have implemented both logical number operations and boolean arrays; and have not been conflicted as to their application. I used boolean arrays to construct very fast indexes for database tables having millions of records. To avoid running out of RAM, creation of megabit arrays should be explicit; so the boolean array procedures put their results into a passed array. In contrast, these procedures are purely functional.
The logior, logxor, logand, lognot, logtest, logbit? (logbitp), ash, logcount, and integer-length procedures are from Common-Lisp. Logior, logxor, and logand have been extended to accept one or more arguments. Opportunities to use an n-ary version of logtest have not been frequent enough to justify its extension.
In the Bitwise Operations, rather than striving for orthogonal completeness, I have concentrated on a nearly minimal set of bitwise logical functions sufficient to support the uses listed above.
Although any two of logior, logxor, and logand (in combination with lognot) are sufficient to generate all the two-input logic functions, having these three means that any nontrivial two-input logical function can be synthesized using just one of these two-input primaries with zero or one calls to lognot.
The Bit Within Word and Field of Bits procedures are used for modeling digital logic and accessing C data structures.
Development of the Bit order and Lamination procedures were driven by digital logic modeling and the implementation of the Hilbert-Peano space-filling function.
Gray codes are useful for communication between asynchronous processes in both hardware and software; and are integral to the implementation of the Hilbert-Peano space-filling function.
Example:
(number->string (logand #b1100 #b1010) 2) => "1000"
Example:
(number->string (logior #b1100 #b1010) 2) => "1110"
Example:
(number->string (logxor #b1100 #b1010) 2) => "110"
Example:
(number->string (lognot #b10000000) 2) => "-10000001" (number->string (lognot #b0) 2) => "-1"
(logtest j k) == (not (zero? (logand j k))) (logtest #b0100 #b1011) => #f (logtest #b0100 #b0111) => #t
Example:
(logcount #b10101010) => 4 (logcount 0) => 0 (logcount -2) => 1
Example:
(integer-length #b10101010) => 8 (integer-length 0) => 0 (integer-length #b1111) => 4
(logbit? index j) == (logtest (expt 2 index) j) (logbit? 0 #b1101) => #t (logbit? 1 #b1101) => #f (logbit? 2 #b1101) => #t (logbit? 3 #b1101) => #t (logbit? 4 #b1101) => #f
#t
and 0 if bit is #f
.
Example:
(number->string (copy-bit 0 0 #t) 2) => "1" (number->string (copy-bit 2 0 #t) 2) => "100" (number->string (copy-bit 2 #b1111 #f) 2) => "1011"
Example:
(number->string (bit-field #b1101101010 0 4) 2) => "1010" (number->string (bit-field #b1101101010 4 9) 2) => "10110"
Example:
(number->string (copy-bit-field #b1101101010 0 4 0) 2) => "1101100000" (number->string (copy-bit-field #b1101101010 0 4 -1) 2) => "1101101111"
(inexact->exact (floor (* n (expt 2 count))))
.
Example:
(number->string (ash #b1 3) 2) => "1000" (number->string (ash #b1010 -1) 2) => "101"
Example:
(number->string (logical:rotate #b0100 3 4) 2) => "10" (number->string (logical:rotate #b0100 -1 4) 2) => "10"
(number->string (bit-reverse 8 #xa7) 16) => "e5"
For any non-negative integers k and count:
(eqv? k (bitwise:laminate (bitwise:delaminate count k)))
integer->list
returns a list of len booleans corresponding
to each bit of the given integer. #t is coded for each 1; #f for 0.
The len argument defaults to (integer-length k)
.
list->integer
returns an integer formed from the booleans in the
list list, which must be a list of booleans. A 1 bit is coded for
each #t; a 0 bit for #f.
integer->list
and list->integer
are inverses so far as
equal?
is concerned.
A Gray code is an ordering of non-negative integers in which exactly one bit differs between each pair of successive elements. There are multiple Gray codings. An n-bit Gray code corresponds to a Hamiltonian cycle on an n-dimensional hypercube.
Gray codes find use communicating incrementally changing values between asynchronous agents. De-laminated Gray codes comprise the coordinates of Peano-Hilbert space-filling curves.
integer-length
as
k.
integer-length
as k.
For any non-negative integer k,
(eqv? k (gray-code->integer (integer->gray-code k)))
For any non-negative integers k1 and k2, the Gray code
predicate of (integer->gray-code k1)
and
(integer->gray-code k2)
will return the same value as the
corresponding predicate of k1 and k2.
This document and translations of it may be copied and furnished to others, and derivative works that comment on or otherwise explain it or assist in its implementation may be prepared, copied, published and distributed, in whole or in part, without restriction of any kind, provided that the above copyright notice and this paragraph are included on all such copies and derivative works. However, this document itself may not be modified in any way, such as by removing the copyright notice or references to the Scheme Request For Implementation process or editors, except as needed for the purpose of developing SRFIs in which case the procedures for copyrights defined in the SRFI process must be followed, or as required to translate it into languages other than English.
The limited permissions granted above are perpetual and will not be revoked by the authors or their successors or assigns.
This document and the information contained herein is provided on an "AS IS" basis and THE AUTHOR AND THE SRFI EDITORS DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.