cl-minifloats

2026-01-01

Minifloats (minifloat < single-float) support for Common Lisp

Upstream URL

Author

Artyom Bologov

License

BSD-2 Clause
README

1cl-minifloats

cl-minifloats is an experiment with [[https://en.wikipedia.org/wiki/Minifloat][minifloats, floats below 16 bit width]].

Right now, only one set of operations is supported—conversion from and to different (8-, 6-, 4-, 3-, and 2-bit floats) formats to/from CL (single) float. It's unlikely there will be other operations, because CL implemenations' float operations are FAST. Hard to compete with these on a custom binary format. But who knows?

1.1Getting Started

1.1.1Library user setup

If you want to use the library without hacking on it, clone the Git repository to where ASDF can find it:
  git clone --recursive https://codeberg.org/aartaka/cl-minifloats ~/.local/share/common-lisp/source/

And then load :cl-minifloats in the REPL:

  (asdf:load-system :cl-minifloats)
  ;; or, if you use Quicklisp
  (ql:quickload :cl-minifloats)

Note that one hard dependency is float-features. Install it first.

1.1.2Contributor/developer setup

In case you want to hack on cl-minifloat, all the dependencies are bundled as submodules, so you need to do a recursive clone
  git clone --recursive https://codeberg.org/aartaka/cl-minifloats

After that, you can run an Emacs-friendly development server with

  make slynk
  # or
  make swank

or tests with

  make check

1.2Examples

Pre-defined (sign.exponent.significand±bias) floats are (see ./package.lisp for up-to-date info):
  • 1.4.3
  • 1.4.3-2
  • 1.3.4
  • 1.3.2
  • 1.2.1
  • 1.1.1
  • 0.2.1
  • 0.1.1

And a special 1.2.1-abnormal that Wikipedia mentioned.

CL-minifloat provides conversion from specific minifloat types to CL's single-float.

  (cl-minifloats:1.4.3-2-to-float #b00000000)
  ;; => 0.0
  (cl-minifloats:1.4.3-2-to-float #b00001011)
  ;; => 11.0

  (cl-minifloats:1.2.1-to-float #b0010)
  ;; => 1.0 (100.0%)

  (cl-minifloats:1.2.1-abnormal-to-float #b0001)
  ;; => 0.5 (50.0%)
  (cl-minifloats:1.2.1-abnormal-to-float #b0101)
  ;; => 3.0

You can define new types, like 16-bit half-floats

  ;; Define half-floats
  (cl-minifloats:define-x->float 1 5 10)
  (1.5.10-to-float #b0000000000000000)
  ;; => 0.0
  (1.5.10-to-float #b0000001111111111)
  ;; => 6.097555e-5 (0.006097555%)
  (1.5.10-to-float #b0011110000000001)
  ;; => 1.0009766 (100.09766%)
  (1.5.10-to-float #b0111110000000000)
  ;; => #.SINGLE-FLOAT-POSITIVE-INFINITY

There are predefined infinity/NaN values for all the built-in (except 1.2.1-abnormal) and user-defined types:

  (cl-minifloats:1.2.1-to-float cl-minifloats:1.2.1-nan)
  ;; => #<single-float quiet NaN>

  (cl-minifloats:0.1.1-to-float cl-minifloats:0.1.1-infinity)
  ;; => #<single-float positive infinity>

  (cl-minifloats:1.4.3-to-float cl-minifloats:1.4.3-positive-infinity)
  ;; => #<single-float positive infinity>

  (cl-minifloats:1.4.3-to-float cl-minifloats:1.4.3-negative-infinity)
  ;; => #<single-float negative infinity>

  (cl-minifloats:1.4.3-to-float cl-minifloats:most-positive-1.4.3)
  ;; => 240.0

  (cl-minifloats:1.4.3-to-float cl-minifloats:most-negative-1.4.3)
  ;; => -240.0

  (cl-minifloats:1.4.3-to-float cl-minifloats:least-positive-1.4.3)
  ;; => 0.001953125 (0.1953125%)

  (cl-minifloats:1.4.3-to-float cl-minifloats:least-negative-1.4.3)
  ;; => -0.001953125 (-0.1953125%)

Note that arithmetic/math operations are not provided (yet?) because they are hard to get right and will likely be slower than implementation-specific single float ops. Conversion from minifloat to single float might be preferable for computations. God, even mature implementation convert minifloats to 32-bit for computations! Thus minifloats might serve as transport or storage format, not the actual computation ones.

But if you happen to know and implement fast arithmetics for minifloats, I'll be glad to accept patches!

2TODO:

  • NVFP4
  • FP4
  • MXFP4
  • MXFP6
  • MXFP8
  • BF16

Dependencies (4)

  • float-features
  • lisp-unit2
  • slime
  • sly

Dependents (0)

    • GitHub
    • Quicklisp