BSD-3-Clause licensed by Levent Erkok
Maintained by [email protected]
This version can be pinned in stack with:crackNum-3.31@sha256:94bedb6a1a86fe87d1368fe67798b1120dabcaf64ca2e8c0714d6a06da17f48d,2259

Module documentation for 3.31

There are no documented modules for this package.

Decode/Encode Integers, Words, and IEEE754 and other float formats

On Hackage: http://hackage.haskell.org/package/crackNum

crackNum shows you exactly how a number is laid out in memory: the bit pattern, its fields, the classification, and the value in binary, octal, decimal, and hex. It works in both directions:

  • Encoding: give it a value (2.5, -2.3e6, NaN, 0x3.2p5), and it shows the bit-pattern it turns into, together with the rounding that took place.
  • Decoding: give it a bit-pattern (0xdeadbeef, 0b0110, 32'hfdc71fc6), and it shows the value it stands for.

Installation

Prebuilt binaries (nothing to build, no Haskell toolchain)

The easiest way to get crackNum is from the Releases page. Each bundle is self-contained: the crackNum executable, a copy of z3, the graphical interface, a LICENSE, and a README repeating the steps below.

Platform Asset Notes
Linux (x86_64) crackNum-<version>-linux-x86_64.tar.gz Statically linked, so there is no glibc or distribution requirement: it runs as-is on any x86_64 Linux, old or new.
macOS (Apple Silicon) crackNum-<version>-macos-arm64.tar.gz Includes CrackNum.app. Ad-hoc signed rather than notarized, so clear the quarantine flag as shown below.

Unpack the bundle anywhere you like, then put the files somewhere on your PATH. z3 has to go there too, since crackNum shells out to it for every operation.

Linux — all three files, the GUI script included:

$ tar xzf crackNum-<version>-linux-x86_64.tar.gz
$ cd crackNum-<version>-linux-x86_64
$ mkdir -p ~/bin && cp crackNum z3 crackNum.tcl ~/bin/
$ export PATH=$HOME/bin:$PATH        # put this in your shell's startup file

The GUI is a Tcl/Tk script, so unlike the two binaries it needs something from your system: wish on your PATH. Install it with sudo apt install tk (Debian/Ubuntu), sudo dnf install tk (RHEL/Fedora), or nix profile install nixpkgs#tk.

macOS — clear the quarantine flag first, since these are ad-hoc signed rather than notarized and nothing will run before you do:

$ tar xzf crackNum-<version>-macos-arm64.tar.gz
$ cd crackNum-<version>-macos-arm64
$ xattr -dr com.apple.quarantine crackNum z3 CrackNum.app
$ mkdir -p ~/bin && cp crackNum z3 ~/bin/
$ cp -R CrackNum.app /Applications/
$ export PATH=$HOME/bin:$PATH        # put this in your login shell's startup file

Either way, check with:

$ crackNum -fsp 3.5
$ crackNum --gui

From Hackage

$ cabal install crackNum

Installed this way you also need z3 on your PATH: crackNum delegates the floating-point reasoning to it, via SBV.

Supported formats

Flag        Format                               Exponent   Significand
-----------------------------------------------------------------------
-fhp        Half precision (IEEE-754 binary16)          5            11
-fbp        Brain float (bfloat16)                      8             8
-ftf32      TensorFloat-32                              8            11
-fsp        Single precision (binary32)                 8            24
-fdp        Double precision (binary64)                11            53
-fqp        Quad precision (binary128)                 15           113
-fe5m2      FP8, IEEE-754 style                         5             3
-fe4m3      FP8, alternate (no infinities)              4             4
-ffp4       FP4 (E2M1)                                  2             2
-ffp4e0m3   FP4 (E0M3), sign-magnitude                  0             3
-fe8m0      E8M0 (MX scale), exponent-only              8             0
-fa+b       Arbitrary IEEE-754 float                    a             b

Significand sizes include the implicit bit.

FP4 (E0M3) is the odd one out: with no exponent bits at all it is really a 4-bit sign-magnitude integer, holding a sign and a 3-bit magnitude. It covers -7 to 7, with both a positive and a negative zero, and has neither NaN nor Inf.

E8M0 is the odd one out in the other direction: it is the shared scale of the OCP Microscaling (MX) formats, and is all exponent. With no sign bit and no significand, every value it holds is a power of two, from 2^-127 to 2^127. It has no zero and no subnormals – an all-zero encoding means 2^-127, not zero – and no infinities; 0xFF is its one and only NaN. Negative inputs are rejected, and values outside its range saturate to the nearest end-point.

Integers come in two flavors: -iN for a signed N-bit 2’s complement integer, and -wN for an unsigned N-bit word. Both N and the arbitrary float sizes can be as large as you like, within machine-word limits.

Note that TF32 is cracked as its 19 architectural bits; hardware typically carries these in a 32-bit container with the remaining bits unused.

Rounding mode is selected with -r, and defaults to RNE if not given: RNE (nearest, ties to even), RNA (nearest, ties away), RTP (towards positive infinity), RTN (towards negative infinity), and RTZ (towards zero).

Example: Encode a decimal number as a single-precision IEEE754 number

$ crackNum -fsp -- -2.3e6
Satisfiable. Model:
  ENCODED = -2300000.0 :: Float
                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------S23----------
   Binary layout: 1 10010100 00011000110000110000000
      Hex layout: CA0C 6180
       Precision: Single
            Sign: Negative
        Exponent: 21 (Stored: 148, Bias: 127)
  Classification: FP_NORMAL
          Binary: -0b1.0001100011000011p+21
           Octal: -0o1.061414p+21
         Decimal: -2300000.0
             Hex: -0x2.3186p+20
   Rounding mode: RNE: Round nearest ties to even.
            Note: Conversion from "-2.3e6" was exact. No rounding happened.

Example: Encode with a different rounding mode

$ crackNum -fsp 1.3 -rRTZ
Satisfiable. Model:
  ENCODED = 1.3 :: Float
                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------S23----------
   Binary layout: 0 01111111 01001100110011001100110
      Hex layout: 3FA6 6666
       Precision: Single
            Sign: Positive
        Exponent: 0 (Stored: 127, Bias: 127)
  Classification: FP_NORMAL
          Binary: 0b1.0100110011001100110011
           Octal: 0o1.23146314
         Decimal: 1.3
             Hex: 0x1.4ccccc
   Rounding mode: RTZ: Round towards zero.
            Note: Conversion from "1.3" was not faithful. Status: Inexact.

Example: Decode a single-precision IEEE754 number float from memory-layout

$ crackNum -fsp  0xfc00 abc1
Satisfiable. Model:
  DECODED = -2.6723903e36 :: Float
                  3  2          1         0
                  1 09876543 21098765432109876543210
                  S ---E8--- ----------S23----------
   Binary layout: 1 11111000 00000001010101111000001
      Hex layout: FC00 ABC1
       Precision: Single
            Sign: Negative
        Exponent: 121 (Stored: 248, Bias: 127)
  Classification: FP_NORMAL
          Binary: -0b1.00000001010101111000001p+121
           Octal: -0o2.00527404p+120
         Decimal: -2.6723903e36
             Hex: -0x2.02af04p+120

Example: Encode as an E4M3 FP8 float

$ crackNum -fe4m3 2.5
Satisfiable. Model:
  ENCODED = 2.5 :: E4M3
                  7 6543 210
                  S -E4- S3-
   Binary layout: 0 1000 010
      Hex layout: 42
       Precision: 4 exponent bits, 3 significand bits
            Sign: Positive
        Exponent: 1 (Stored: 8, Bias: 7)
  Classification: FP_NORMAL
          Binary: 0b1.01p1
           Octal: 0o2.4
         Decimal: 2.5
             Hex: 0x2.8

Example: Decode an FP4 (E2M1) float

$ crackNum -ffp4 0b0111
Satisfiable. Model:
  DECODED = 6.0 :: FP4
                  3 21 0
                  S E2 S
   Binary layout: 0 11 1
      Hex layout: 7
       Precision: 2 exponent bits, 1 significand bit
            Sign: Positive
        Exponent: 2 (Stored: 3, Bias: 1)
  Classification: FP_NORMAL
          Binary: 0b1.1p+2
           Octal: 0o6
         Decimal: 6.0
             Hex: 0x6

Example: Decode an FP4 (E0M3) sign-magnitude integer

$ crackNum -ffp4e0m3 0b1101
Satisfiable. Model:
  DECODED = -5 :: FP4E0M3
                  3 210
                  S -M-
   Binary layout: 1 101
      Hex layout: D
            Type: 4-bit sign-magnitude integer
            Sign: Negative
          Binary: -0b101
           Octal: -0o5
         Decimal: -5
             Hex: -0x5

Example: Encode an FP4 (E0M3) sign-magnitude integer

$ crackNum -ffp4e0m3 -- -5
Satisfiable. Model:
  ENCODED = -5 :: FP4E0M3
                  3 210
                  S -M-
   Binary layout: 1 101
      Hex layout: D
            Type: 4-bit sign-magnitude integer
            Sign: Negative
          Binary: -0b101
           Octal: -0o5
         Decimal: -5
             Hex: -0x5
   Rounding mode: RNE: Round nearest ties to even.
            Note: Conversion from "-5" was exact. No rounding happened.

Example: Decode an E8M0 MX scale

$ crackNum -fe8m0 0xFE
Satisfiable. Model:
  DECODED = 1.7014118346046923e38 :: E8M0
                  76543210
                  ---E8---
   Binary layout: 11111110
      Hex layout: FE
       Precision: 8 exponent bits, no significand
            Sign: Positive (always)
        Exponent: 127 (Stored: 254, Bias: 127)
  Classification: FP_NORMAL
          Binary: 0b1p+127
           Octal: 0o2p+126
         Decimal: 1.7014118346046923e38
             Hex: 0x8p+124

Example: Encode an E8M0 MX scale

Only powers of two are representable, so everything else rounds according to -r:

$ crackNum -fe8m0 -- 10
Satisfiable. Model:
  ENCODED = 8.0 :: E8M0
                  76543210
                  ---E8---
   Binary layout: 10000010
      Hex layout: 82
       Precision: 8 exponent bits, no significand
            Sign: Positive (always)
        Exponent: 3 (Stored: 130, Bias: 127)
  Classification: FP_NORMAL
          Binary: 0b1p+3
           Octal: 0o1p+3
         Decimal: 8.0
             Hex: 0x8
   Rounding mode: RNE: Round nearest ties to even.
            Note: Original value of 10.0 was rounded to 8.0.

Example: Encode a TensorFloat-32 number

$ crackNum -ftf32 2.5
Satisfiable. Model:
  ENCODED = 2.5 :: FloatingPoint 8 11
                  1          0
                  8 76543210 9876543210
                  S ---E8--- ---S10----
   Binary layout: 0 10000000 0100000000
      Hex layout: 2 0100
       Precision: 8 exponent bits, 10 significand bits
            Sign: Positive
        Exponent: 1 (Stored: 128, Bias: 127)
  Classification: FP_NORMAL
          Binary: 0b1.01p1
           Octal: 0o2.4
         Decimal: 2.5
             Hex: 0x2.8
   Rounding mode: RNE: Round nearest ties to even.
            Note: Conversion from "2.5" was exact. No rounding happened.

Example: Decode a custom (2+3) float from memory-layout

$ crackNum -f2+3 0b10011
Satisfiable. Model:
  DECODED = -0.75 :: FloatingPoint 2 3
                  4 32 10
                  S E2 S2
   Binary layout: 1 00 11
      Hex layout: 13
       Precision: 2 exponent bits, 2 significand bits
            Sign: Negative
        Exponent: 0 (Subnormal, with fixed exponent value. Stored: 0, Bias: 1)
  Classification: FP_SUBNORMAL
          Binary: -0b1.1p-1
           Octal: -0o6p-3
         Decimal: -0.75
             Hex: -0xcp-4

Example: Encode an integer as a 7-bit signed word

$ crackNum -i7 12
Satisfiable. Model:
  ENCODED = 12 :: IntN 7
                  654 3210
   Binary layout: 000 1100
      Hex layout: 0C
            Type: Signed 7-bit 2's complement integer
            Sign: Positive
          Binary: 0b1100
           Octal: 0o14
         Decimal: 12
             Hex: 0xc

Example: Decode a 4-bit unsigned word

$ crackNum -w4 0xE
Satisfiable. Model:
  DECODED = 14 :: WordN 4
                  3210
   Binary layout: 1110
      Hex layout: E
            Type: Unsigned 4-bit word
          Binary: 0b1110
           Octal: 0o16
         Decimal: 14
             Hex: 0xe

Example: Decode two half-precision floats in two lanes

$ crackNum -l2 -fhp 32\'hfdc71fc6
== Lane 1 ============================================================
Satisfiable. Model:
  DECODED = NaN :: FloatingPoint 5 11
                  1       0
                  5 43210 9876543210
                  S -E5-- ---S10----
   Binary layout: 1 11111 0111000111
      Hex layout: FDC7
       Precision: Half (5 exponent bits, 10 significand bits.)
            Sign: Negative
        Exponent: 16 (Stored: 31, Bias: 15)
  Classification: FP_NAN (Signaling)
           Value: NaN
            Note: Representation for NaN's is not unique
== Lane 0 ============================================================
Satisfiable. Model:
  DECODED = 0.0075912476 :: FloatingPoint 5 11
                  1       0
                  5 43210 9876543210
                  S -E5-- ---S10----
   Binary layout: 0 00111 1111000110
      Hex layout: 1FC6
       Precision: Half (5 exponent bits, 10 significand bits.)
            Sign: Positive
        Exponent: -8 (Stored: 7, Bias: 15)
  Classification: FP_NORMAL
          Binary: 0b1.111100011p-8
           Octal: 0o3.706p-9
         Decimal: 0.0075912476
             Hex: 0x1.f18p-8

If you use the verilog notation (N'h...), the number of lanes is inferred from the width, so -l is optional in that case.

Graphical interface (optional)

Optionally, crackNum comes with a GUI: pick a format on the left, type a value, and see the encoding/decoding in detail. It is entirely optional — crackNum is fully functional as a command-line tool without it. The GUI is just a thin front-end that calls the crackNum binary underneath, so it supports exactly the same formats.

If you installed from a release bundle the GUI is already in it, and there is nothing to build on either platform. The rest of this section is for installing from Hackage or from a source checkout.

macOS — a native Swift/AppKit app (GUI/swiftGUI/). It is not part of the Hackage package, so building it yourself needs a clone of the repository and the Swift compiler that comes with the Xcode Command Line Tools (xcode-select --install):

$ git clone https://github.com/LeventErkok/crackNum.git
$ cd crackNum/GUI/swiftGUI
$ make install      # builds CrackNum.app and copies it into /Applications

Linux — a Tcl/Tk script (GUI/tclGUI/crackNum.tcl). The script ships with the package and is installed alongside the binary, so there is nothing to build; you only need wish (Tk 8.6+):

$ nix profile install nixpkgs#tk   # or: sudo apt install tk / sudo dnf install tk

Then crackNum --gui just works. If you want to run a modified copy of the script, either put it on your PATH as crackNum.tcl, or point at it directly with CRACKNUM_TCL=/path/to/crackNum.tcl.

On both platforms, launch the GUI from the command line via the --gui option, which forwards any format/rounding flags and value to the app:

$ crackNum --gui                 -- open the graphical interface
$ crackNum --gui -fsp 2.5        -- open it with single-precision selected, and 2.5 cracked
$ crackNum --gui 0xdeadbeef      -- open it pre-filled with a value to decode

Bad flags are diagnosed before the GUI comes up: crackNum -ft32 4 --gui reports the unknown format instead of opening an empty window.

Usage info

Usage: crackNum value OR binary/hex-pattern
  -i N                      Signed   integer of N-bits
  -w N                      Unsigned integer of N-bits
  -f fp                     Floating point format fp
  -r rm                     Rounding mode to use. If not given, Nearest-ties-to-Even.
  -l lanes                  Number of lanes to decode
  -h, -?    --help          print help, with examples
  -v        --version       print version info
  -d        --debug         debug mode, developers only
            --gui           launch the graphical interface
            --list-formats  list the formats supported by -f, one per line

Supported floating-point formats (for use with -f):

       hp: Half float             ( 5 +  11)
       bp: Brain float            ( 8 +   8)
     tf32: TensorFloat-32         ( 8 +  11)
       sp: Single precision       ( 8 +  24)
       dp: Double precision       (11 +  53)
       qp: Quad   precision       (15 + 113)
      a+b: Arbitrary IEEE-754     ( a +   b)
     e5m2: FP8 format (IEEE-754)  ( 5 +   3)
     e4m3: FP8 format (Alternate) ( 4 +   4)
      fp4: FP4 format (E2M1)      ( 2 +   2)
  fp4e0m3: FP4 format (E0M3)      ( 0 +   3)
     e8m0: FP8 format (MX scale)  ( 8 +   0)

Examples:
 Encoding:
   crackNum -i4       -- -2                   -- encode as 4-bit signed integer
   crackNum -w4       2                       -- encode as 4-bit unsigned integer
   crackNum -f3+4     2.5                     -- encode as float with 3 bits exponent, 4 bits significand
   crackNum -f3+4     2.5 -rRTZ               -- encode as above, but use RTZ rounding mode.
   crackNum -fbp      2.5                     -- encode as a brain-precision float
   crackNum -ftf32    2.5                     -- encode as a TensorFloat-32 float
   crackNum -fdp      2.5                     -- encode as a double-precision float
   crackNum -fqp      2.5                     -- encode as a quad-precision float
   crackNum -fe4m3    2.5                     -- encode as an E4M3 FP8 float
   crackNum -fe5m2    2.5                     -- encode as an E5M2 FP8 float
   crackNum -ffp4     2.5                     -- encode as an FP4 (E2M1) float
   crackNum -ffp4e0m3 3.5                     -- encode as an FP4 (E0M3) sign-magnitude integer
   crackNum -fe8m0    2.5                     -- encode as an E8M0 MX scale (power of two)
   crackNum -fsp      0x3.2p5                 -- encode as single-precision from hex-float

 Decoding:
   crackNum -i4       0b0110                  -- decode as 4-bit signed integer, from binary
   crackNum -w4       0xE                     -- decode as 4-bit unsigned integer, from hex
   crackNum -f3+4     0b0111001               -- decode as float with 3 bits exponent, 4 bits significand
   crackNum -fbp      0x000F                  -- decode as a brain-precision float
   crackNum -ftf32    19\'h0000F              -- decode as a TensorFloat-32 float
   crackNum -fdp      0x8000000000000000      -- decode as a double-precision float
   crackNum -fhp      0x8000                  -- decode as a half-precision float
   crackNum -ffp4     0b0111                  -- decode as an FP4 (E2M1) float
   crackNum -ffp4e0m3 0b1101                  -- decode as an FP4 (E0M3) sign-magnitude integer
   crackNum -fe8m0    0x7F                    -- decode as an E8M0 MX scale (power of two)
   crackNum -l4 -fhp  64\'hbdffaaffdc71fc60   -- decode as half-precision float over 4 lanes using verilog notation

 GUI:
   crackNum --gui                             -- launch the graphical interface
   crackNum --gui      0xdeadbeef             -- launch the GUI, pre-filled with the given value
   crackNum --gui -fsp 0xdeadbeef             -- launch the GUI, using the given format

 Notes:
   - For encoding:
       - Use -- to separate your argument if it's a negative number.
       - For floats: You can pass in NaN, Inf, -0, -Inf etc as the argument
                     along with a decimal (2.3, -4.1e5) or hexadecimal float (0x2.4p3)
       - FP4 (E2M1) has neither NaN nor Inf, so those inputs are rejected. Finite
         values outside its range of [-6, 6] saturate to the nearest end-point.
       - FP4 (E0M3) is a sign-magnitude integer: a sign bit and a 3-bit magnitude,
         covering -7 to 7, with both a positive and a negative zero. It has no NaN
         and no Inf either, and values outside [-7, 7] saturate to the end-point.
       - E8M0 (MX scale) is all exponent: no sign bit and no significand at all,
         so every value is a power of two, from 2^-127 to 2^127. It has no zero
         and no Inf, and 0xFF is its only NaN. Negative inputs are rejected;
         values outside the range saturate to the nearest end-point.
   - For decoding:
       - Use hexadecimal (0x) binary (0b), or N'h (verilog) notation as input.
         Input must have one of these prefixes.
       - You can use _,- or space as a digit to improve readability for the pattern to be decoded
       - With -lN parameter, you can decode multiple lanes of data.
       - If you use verilog input format, then we will infer the number of lanes unless you provide it.

VIM users: You can use the http://github.com/LeventErkok/crackNum/blob/master/crackNum.vim file to use CrackNum directly from VIM. Simply locate your cursor on the text to crack, and use the command :CrackNum options.

Changes

Version 3.31, Not yet released

  • The Hackage description now shows a screenshot of the GUI, and points at the releases page for the prebuilt Mac and Linux bundles. The screenshot was dropped from README.md in the same breath: Hackage renders the README below the description, so keeping it in both would have shown the same image twice on one page.

  • The READMEs shipped inside the binary bundles now walk through a single install sequence – unpack, place the files, set PATH, check – instead of splitting the CLI and the GUI into separately numbered steps that had to cross-reference each other. The macOS one leads with the quarantine removal, since nothing runs before that.

Version 3.30, 2026-08-21

  • The GUIs now group the floating-point formats by provenance instead of listing all twelve of them in one flat “Float” section. The formats that exist because of machine learning – FP4 (E2M1), FP4 (E0M3), FP8 (E4M3), FP8 (E5M2), FP8 (E8M0), Brain, and TF32 – come first under “AI formats”, followed by the IEEE-754 ones (Half, Single, Double, Quad, and Custom) under “IEEE-754”. Integers now precede words, so the sidebar reads AI formats, IEEE-754, Integer (Signed), Word (Unsigned). Both the macOS (Swift) and the Tcl/Tk GUI are grouped identically. No format was added, removed, or renamed, and the command line is unaffected.

  • The “Custom parameters” box in the GUIs is now titled “Custom IEEE-754 float:”, and its heading lines up flush left with “Rounding mode” above it rather than being indented past it. The “(exponent width applies to custom floats)” note is gone, the new title having made it redundant. Note that the “Total width” field also applies to the Custom entries under Integer (Signed) and Word (Unsigned), which take a width but no exponent.

  • The format list in the Tcl/Tk GUI now has a vertical scrollbar. With four sections it is taller than the sidebar at the default window size, and without a scrollbar the formats past the bottom were not merely off-screen but unreachable. (The macOS GUI needed no equivalent change; its list already scrolled.)

  • Scrollbars in the Tcl/Tk GUI now appear only when there is something to scroll to, rather than always taking up room. This covers the output pane’s pair as well as the new one on the format list.

  • Internally, Main.hs has been split into per-topic modules – CrackNum.Types, .Formats, .Options, .Utils, .Output, .GUI, .Decode, and .Encode – leaving Main with just the argument dispatch. It had grown to some 1400 lines holding everything from option parsing to the hand-rolled layouts for the formats that have no IEEE look-alike. This is purely a reorganization: every definition moved verbatim, so there is no change in behavior or output.

Version 3.29, 2026-08-21

  • crackNum.vim’s TAB completion no longer offers a hardcoded set of -lN lane counts, since -lN is never valid on its own and always needs pairing with a -f/-i/-w flag; type it directly instead. -i/-w completion now offers the bare flag and prompts for the bit-width separately, rather than baking in a fixed set of widths – crackNum accepts any -iN/-wN, so there was never a complete list to offer.

Version 3.28, 2026-08-21

  • Add support for the E8M0 format, via -fe8m0. This is the shared scale of the OCP Microscaling (MX) formats: the value that scales a block of MXFP8/MXFP6/MXFP4 elements, all of which crackNum already knew about. It is the mirror image of FP4 (E0M3): where that format is all significand and no exponent, E8M0 is all exponent and no significand, with no sign bit either. Every value it holds is therefore a power of two, from 2^-127 to 2^127.

    Note that it has no zero and no subnormals – with nothing for the all-zero encoding to mean, it simply denotes 2^-127 – and no infinities. 0xFF is its one and only NaN. Negative inputs are rejected rather than saturated: with no sign bit there is no direction to saturate towards, and clamping would quietly turn a negative into a positive. Values outside the range, infinity included, saturate to the nearest end-point, and anything that is not a power of two rounds according to -r.

Version 3.27, 2026-08-20

  • There is now a Linux binary distribution, alongside the macOS one: see the Releases page. It ships the crackNum executable, a copy of z3 (which crackNum shells out to for every operation), the Tcl/Tk GUI script, and a README. Both binaries are statically linked, so there is no libc or distribution requirement: they run as-is on any x86_64 Linux, old or new. The GUI additionally needs wish, which does have to come from your system.

  • --gui now also looks for crackNum.tcl next to the crackNum executable itself, after $CRACKNUM_TCL and the PATH but before the cabal data-directory. A binary distribution carries the script alongside the binary, where the data-directory baked in at build time names a path from the build machine that does not exist on the user’s; the GUI now works in such a bundle however it is unpacked or copied, rather than only when the script was also placed on the PATH.

Version 3.26, 2026-08-19

  • New flag --list-formats, which prints the floating-point formats -f accepts, one name per line. It is meant for editor integrations, which would otherwise have to hardcode the list and let it go stale; the VIM plugin now asks rather than guesses, and picks up any format added later for free.

  • --help now also lists the supported floating-point formats. Both it and the -f error message are generated from a single table, so they cannot disagree.

  • Fix the VIM integration, which had been broken since version 3.0. The plugin offered i, w, and f as the choices at its precision prompt, and passed whichever you picked through as-is, so :CrackNum ran crackNum i 0b0110: no leading dash, and no bit-width. Every invocation was rejected, and the quickfix window filled up with crackNum’s usage text instead of an answer. The completion list now offers real flags (-i8, -fhp, …), and anything else crackNum accepts, such as -f3+4 or -l4 -fhp, can be typed in directly.

  • The VIM plugin also set grepformat to VIM %m, matching a --vim output mode that was removed in 3.0. Nothing matched that format, so even a correct invocation produced an empty quickfix window. Take crackNum’s output as-is now.

  • The VIM plugin now finds the bit-pattern under the cursor itself, instead of relying on <cword>. Verilog notation stops at the quote (64'hdeadbeef came out as just 64), and the value is quoted before it reaches the shell.

Version 3.25, 2026-08-18

  • Add support for the FP4 (E0M3) format, via -ffp4e0m3. Unlike every other format crackNum knows about, this one has no exponent bits at all, which makes it a plain 4-bit sign-magnitude integer: a sign bit and a 3-bit magnitude, covering -7 to 7, with both a positive and a negative zero. It has neither NaN nor Inf, so those inputs are rejected; values outside [-7, 7] saturate to the nearest end-point, and fractional inputs round according to -r.

  • Report the format the user actually asked for when decoding E4M3 and FP4. Both are modeled by an IEEE look-alike, and the patterns that need no special handling were printed straight from it, so crackNum -ffp4 0b0100 answered 2.0 :: FloatingPoint 2 2 and crackNum -fe4m3 0b00111000 answered 1.0 :: FloatingPoint 4 4. The values were right, only the type name leaked. The patterns that do deviate, and E5M2 throughout, were already correct.

Version 3.24, 2026-08-17

  • Add a quad-precision example to the help output. -fqp has always been accepted, but --help never mentioned it, so the only way to find out it existed was to trip over the error message for a bad -f argument.

  • Bring the README up to date: document the installation steps (including the z3 requirement), add a table of all supported formats, list the rounding modes, and add worked examples for the FP8, FP4, TF32, and unsigned-word formats. A couple of the existing sample outputs had drifted from what the tool actually prints, and are now regenerated.

Version 3.23, 2026-08-17

  • Do not ignore bad flags when --gui is given. A mistyped format, such as crackNum -ft32 4 --gui, used to bring the GUI up with nothing selected, silently swallowing the error the command line would have reported. We now diagnose the flag first, and only launch the GUI if everything checks out.

  • Add quad-precision (-fqp) to the format list in both GUIs. It was accepted on the command line, but was missing from the interfaces.

Version 3.22, 2026-08-17

  • Fix text alignment in the Tcl/Tk GUI’s entry fields. We asked for the Courier font, which on X11 is an alias that typically resolves to Nimbus Mono PS. Its ascent/descent split is lopsided (9/6 at size 11), and since an entry centers text on the linespace, the glyphs ended up hugging the top of the box with a large gap underneath. We now pick the first monospaced family that is actually installed, preferring ones with sane metrics.

Version 3.21, 2026-08-16

  • Add support for TF32 (TensorFloat-32), via -ftf32. This is the 19-bit format with 8 exponent and 10 significand bits, i.e., the exponent range of single precision with the significand of half precision. Note that we crack the 19 architectural bits; hardware typically carries these in a 32-bit container with the remaining bits unused.

Version 3.20, 2026-08-13

  • Fix tool lookup in both GUIs: a directory named crackNum (or z3) sitting on the PATH was accepted as the executable, since directories carry the search bit and so look executable. The GUI would then fail with a “permission denied” on that directory. We now require a regular file.

Version 3.19, 2026-08-13

  • Fix decoding in the Tcl/Tk GUI: hex and binary input was silently converted to decimal before being handed to crackNum, so entering 0xdeadbeef encoded the value 3735928559 instead of decoding the bit-pattern. Verilog (N'h) input was unaffected.

  • Drop the lane count from both GUIs. The number of lanes is inferred from Verilog (N'h) input, and everything else is a single lane, so there was nothing useful for the interface to set.

Version 3.18, 2026-08-13

  • Add a Tcl/Tk GUI (GUI/tclGUI/crackNum.tcl) that works on Linux and macOS. When --gui is used on Linux, crackNum now launches this interface (requires wish) instead of erroring out.

  • The Tcl/Tk GUI script is now a cabal data-file, so it is installed along with the binary: cabal install crackNum is enough for crackNum --gui to work on Linux, with no PATH setup. To run a different copy of the script, set CRACKNUM_TCL, or put it on your PATH as crackNum.tcl.

  • Both front-ends now live under GUI/: the macOS app moved from gui/ to GUI/swiftGUI/, and the Tcl/Tk script to GUI/tclGUI/.

  • Encoding a NaN now always displays the canonical quiet-NaN pattern (sign 0, all-ones exponent, leading significand bit set; 0x7FC00000 for a single). SMTLib’s floating-point sort has a single NaN value, so the solver returns an abstract NaN and the concrete bit-pattern shown was whatever the model materialized – which could differ between solver/library versions. The E4M3 path already pinned its NaN this way; the rest now do too.

  • Exponent/significand sizes of 1 bit are accepted by -f, but the solver requires at least 2 of each. This now produces a regular error message instead of an uncaught exception with a backtrace.

Version 3.17, 2026-08-10

  • Add support for the FP4 (E2M1) format, via -ffp4. Like E4M3, this format deviates from IEEE-754: The all-ones exponent encodes the values 4 and 6, instead of infinity and NaN. Consequently, FP4 can represent neither NaN nor infinity, and finite values outside of [-6, 6] saturate to the end-points.

Version 3.16, 2026-07-24

  • Add the --gui option, launching a graphical interface (macOS) for interactively encoding/decoding values.

Version 3.15, 2024-11-09

  • Bump up SBV dependence to >= 11.0

Version 3.14, 2024-09-23

  • Fix README

Version 3.13, 2024-09-23

  • Fix help text

Version 3.12, 2024-04-05

  • Fix hexadecimal float parsing for e4m3

Version 3.11, 2024-04-05

  • Allow for encoding of hexadecimal floats

Version 3.10, 2024-03-01

  • More relaxed parsing for verilog input format

Version 3.9, 2024-02-23

  • Fix verilog input format parsing

Version 3.8, 2024-02-21

  • Add support for FP8 formats, as decribed in: https://arxiv.org/pdf/2209.05433.pdf

    • E5M2: Which is essentially a synonym for f5+3
    • E4M3: Similar to f4+4, except it does not have infinities and interprets NaN values differently
  • Fix a bug in cracking of arbitrary-sized floats, that yielded wrong values for some NaN cases

Version 3.7, 2024-02-15

  • Support signaling/quiet indication for decoded NaN values.

  • Add support for decoding over multiple lanes. See the -l option.

  • Add support for verilog bit-vector notation, e.g., 128’hXXX. If you use this notation, crackNum will automatically infer the number of lanes to crack based on the width given; unless explicitly specified.

Version 3.6, 2024-01-24

  • Be more clear when the provided input isn’t a recognizable float, instead of treating it as NaN implicitly. Thanks to Dmitry Blotsky for pointing out the confusion.

Version 3.5, 2024-01-11

  • Resolve compilation issues with GHC 9.8 series

Version 3.4, 2023-04-14

  • Fix compilation in previous build

Version 3.3, 2023-04-14

  • Allow compilation with newer versions of SBV

Version 3.2, 2021-06-30

  • Add an explicit note when conversion is exact.

Version 3.1, 2021-03-29

  • Fix readme

Version 3.0, 2021-03-29

  • A complete rewrite, much simplified, and supporting arbitrary precision floats. Some of the old features and the library are dropped; so if you rely on the library nature of CrackNum, do not upgrade. For other users who merely use crackNum as an executable, the new version is strongly recommended.

Version 2.4, 2020-09-05

  • Changes required to compile cleanly with GHC 8.10.2

Version 2.3, 2018-11-17

  • Remove dependency on the ieee754 and reinterpret-cast packages. The goal is to remove any FFI dependencies. We now define and export the required utilities directly in the CrackNum package.

Version 2.2, 2018-09-01

  • Instead of data-binary-ieee754, use reinterpret-cast package. According to documents, the former is deprecated.

Version 2.1, 2018-07-20

  • Support for vi-editor bindings. See the file “crackNum.vim” in the distribution or in the github repo You can put “so ~/.vim/crackNum.vim” (use the correct path!) and have vi crack numbers directly from inside your editor. Simply locate your cursor on a binary/hex stream of digits and type “:CrackNum”. See the “crackNum.vim” file for binding details.

Version 2.0, 2018-03-17

  • Import FloatingHex qualified to avoid GHC 8.4.1 compilation issue

Version 1.9, 2017-01-22

  • Minor fix to printing of +/-0

Version 1.8, 2017-01-15

  • Bump up FloatingHex dependency to >0.4, this enables proper support for large doubles

Version 1.7, 2017-01-14

  • Fix a snafu in reading hexadecimal floats

Version 1.6, 2017-01-14

  • Add support for hexadecimal-floats. These now work both in toIEEE option as input, and also when printing the values out. (i.e., numbers of the form 0x1.abp-3, etc.)

Version 1.5, 2016-01-23

  • Typo fixes; no functionality changes

Version 1.4, 2016-01-17

  • Fix NaN nomenclature: Screaming->Signaling
  • Add an example to README.md

Version 1.3, 2015-04-11

  • Fix docs, github location

Version 1.2, 2015-04-11

  • Fix the constant qnan values for SP/DP
  • Add conversions from float/double. Much easier to use.
  • Better handling of nan values.

Version 1.1, 2015-04-02

  • Clean-up the API, examples etc.

Version 1.0, 2015-04-01

  • First implementation. Supports HP/SP/DP and signed/unsigned numbers in 8/16/32/64 bits.