Utility library for handling bit vectors, bit vector arithmetic, and universal integer type conversions between bit-vectors, byte-vectors, octals, decimals, and hexadecimal notation.
Common Lisp library for handling bit vectors, bit vector arithmetic, and type conversions.
Available in Quicklisp as of July 2014 release.
Documentation available at: https://thephoeron.common-lisp.dev/bit-smasher/
The current release of BIT-SMASHER compiles without warning and passes all tests on 64-bit versions of the following Lisp implementations:
- SBCL 2.2.5
- Clozure CL 1.12.1
- CLISP 2.49.92
- ABCL 1.9.0
- Allegro CL 10.1
It compiles with warnings on:
- LispWorks 8.0.1
It compiles with style-warnings on:
- ECL 21.2.1
It does not build on:
- CLASP CL 1.0.0 (clasp-boehmprecise-1.0.0-316-gf3b9992a5)
- CMUCL 21d
Usage Notes and Limitations
This library was designed to complement the set of functions included in the Common Lisp specification for handling bit-vectors, by adding relevant lookup, conversion, arithmetic, measurement, and predicate functions. For documentation and tutorials on the bit-vector functions included in the Common Lisp standard, please refer to:
- Common Lisp HyperSpec:
- Successful Lisp: Chapter 18
BIT-SMASHER only handles the set of non-negative integers. As such, arithmetic on bit-vectors may not always produce the results you expect—return values of all arithmetic functions are given as the bit-vector of the absolute ceiling value. Manual conversion of negative integers, floats, fractions, or complex numbers will trigger an error.
The conversion functions allow you to convert universally between bit-vectors, octet-vectors, hexadecimal strings, and non-negative integers.
; universal type-casting style functions (bits<- "F0") => #*11110000 (bits<- 240) => #*11110000 (int<- #*11110000) => 240 ; manual conversions without type-checking (hex->bits "F0") => #*11110000 (int->bits 10) => #*00001010 (octets->bits (int->octets 244)) => #*11110100 ; etc., etc...
Bit-vectors are returned zero-padded to the next full byte.
(bits<- 255) => #*11111111 (bits<- 256) => #*0000000100000000
Arithmetic on bit-vectors can be achieved through the functions
rshift. There are also the shorthand macros,
>>. As stated above, the bit-vector arithmetic
functions return the absolute ceiling value of the operation. So,
(bit- #*0000 #*0010) => #*00000010 ; +2, not -2
The measurement functions
min-bit-length tell you the
maximum and minimum number of bits needed to store a value, respectively. They
operate on bit-vectors, octet-vectors, hexadecimal strings, and non-negative
(wide-bit-length 256) => 16 (min-bit-length 256) => 9
There is also the measurement function
byte-length that returns the total
number of bytes required to store an integer, bit-vector, or hexadecimal value;
or the actual length of byte vector or simple byte array.
(byte-length "A0FF") => 2 (byte-length 65536) => 3
In addition to the built-in CL predicate function,
adds the predicate function
twos-complement-p, when you need to test the
minimum bit length for the two's complement rule. This is required where padding
bit-vectors, octet-vectors, or hex-strings with leading zeros up to a set
word-length is expected.
(twos-complement-p 256) => NIL (twos-complement-p 255) => T
Copyright © 2014–2022, "the Phoeron" Colin J.E. Lupton and the Contributors. This project is released under the MIT License; please see bit-smasher/LICENSE for more information.