Skip to main content

lvext

Lianes8 Certified

Exact pure-Python codec for x87 80-bit extended-precision floats and LabVIEW's flattened EXT.

An x87 extended value is 10 bytes: a C long double on x86 Linux, and the layout of LabVIEW's floatExt, the C type an EXT has when LabVIEW passes it to a library call on Windows. When LabVIEW flattens an EXT (for example into a datalog file) it writes 16 bytes in the IEEE 754 binary128 layout instead. Python's float has 53 bits of precision; an x87 value has 64, and so has every EXT LabVIEW flattens. lvext reads and writes both layouts bit for bit, converts them to and from exact Fraction and Decimal values, and rounds once, in any of the four IEEE modes, wherever precision has to go.

Install

pip install lvext

Python 3.10 or newer, no dependencies.

Quick start

from decimal import Decimal
from fractions import Fraction

from lvext import Ext80, ExtKind, Rounding

# Every float fits exactly. Bytes come out big-endian unless you ask.
one = Ext80.from_float(1.0)
assert one.hex() == "3fff8000000000000000"
assert one.to_bytes("little") == bytes.fromhex("0000000000000080ff3f")

# Decode to the exact value: a Fraction, or a Decimal with every digit.
value = Ext80.from_hex("4000 c90f daa2 2168 c235")
assert value.kind is ExtKind.NORMAL
assert str(value.to_decimal()).startswith("3.14159265358979323851280895940618620443")

# Narrow to a float; the result says whether anything was lost.
assert value.narrow() == (3.141592653589793, False)

# Build from exact numbers, rounding once, in any of the four modes.
third = Ext80.from_fraction(Fraction(1, 3), Rounding.TOWARD_ZERO)
assert third.hex() == "3ffdaaaaaaaaaaaaaaaa"
assert Ext80.from_decimal(Decimal("0.1")).hex() == "3ffbcccccccccccccccd"

# LabVIEW's flattened EXT: 16 bytes, big-endian.
flat = Ext80.from_float(0.1).to_flattened()
assert flat.hex() == "3ffb999999999999a000000000000000"
assert Ext80.from_flattened(flat).to_float() == 0.1

The float-in, float-out helpers of the first release are still there:

from lvext import pack_ext, unpack_ext

assert pack_ext(-2.5) == bytes.fromhex("c000a000000000000000")
assert unpack_ext(pack_ext(-2.5)) == -2.5

Command line

$ lvext encode 1/3
3ffdaaaaaaaaaaaaaaab
$ lvext encode 0.1 --flattened
3ffb999999999999999a000000000000
$ lvext decode 3ffd8000000000000000
kind: normal
sign: +
exponent: 0x3ffd
mantissa: 0x8000000000000000
exact: 0.25
float: 0.25
float_hex: 3fd0000000000000
float_exact: yes
flattened: 3ffd0000000000000000000000000000

lvext --help lists every option; the guide describes them.

How it is verified

  • The x87 FPU itself. On Windows x86-64 the tests run the processor's own load and store instructions through a small test-only ctypes helper and compare lvext with the hardware bit for bit, in all four rounding modes, over edge cases and thousands of random encodings.
  • LabVIEW 2026. 401 pairs of values that LabVIEW 2026 wrote itself, through three shipped VIs with EXT terminals: every double input flattens exactly as LabVIEW wrote it, and 230 products LabVIEW computed in EXT equal lvext's single rounding of the exact product (and differ from each of the other three modes). The guide lists the two corner cases where LabVIEW's bytes and lvext's differ, and why.
  • Exact arithmetic. Golden vectors are exact rationals, rounding is checked against an exact oracle, and seeded fuzzing covers every reader and the command line.

Why

  • Python's struct has no 80-bit or 128-bit float format.
  • numpy.longdouble is the x87 type only where the platform's C long double is (for example Linux on x86 with GCC); on Windows it is an 8-byte double.
  • numpy-quaddtype adds a binary128 dtype to NumPy as a compiled extension; it needs NumPy and does not read the 80-bit layout.

lvext does the bit arithmetic in pure Python, so the same bytes decode the same way on every platform, and it gives the exact value, not just the nearest float.

Documentation

  • Guide: the formats, every public name, rounding, special values, LabVIEW details, errors and upgrading from 0.2.
  • Changelog

License

MIT. See LICENSE.

Metadata

Release files for lvext 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lvext 1.0.0
File Size Uploaded
lvext-1.0.0.tar.gz 56.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lvext 1.0.0
File Interpreter ABI Platform
lvext-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 80.0 kB

Release files / lvext-1.0.0.tar.gz

Download URL lvext-1.0.0.tar.gz
Size 56.3 kB
Tags Source
SHA-256 checksum
How to use checksums
4db1f42d97ca5b6abbcec32d17f3780f92a8731b5ff75fc5d538f58bbffa4a43
BLAKE2b-256 checksum
How to use checksums
91eedbaef2445664cd4b06d6d382bd66258411ef12385f42702fd57e2c3cf443
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release files / lvext-1.0.0-py3-none-any.whl

Download URL lvext-1.0.0-py3-none-any.whl
Size 23.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6fd74e63678221006cd66de936754f9a9dc9810ebfdda0faf2ef72ff9524887f
BLAKE2b-256 checksum
How to use checksums
190ca9510a5fc2460eb95914f0f3fbeba7848a9fbc77ae26cb3233c8223c3572
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.2

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page