zerodds_float128/lib.rs
1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! Crate `zerodds-float128`. Safety classification: **SAFE**.
4//!
5//! IEEE 754 binary128, in software.
6//!
7//! CDR gives `long double` sixteen bytes and CORBA 3.3 part 2 §9.3.1.3
8//! says what is in them: one sign bit, a fifteen-bit exponent biased by
9//! 16383, and a 112-bit stored fraction. That is binary128, and
10//! DDS-XTypes 1.3 Table 31 names it — "IEEE standard for normalized
11//! quadruple-precision floating-point numbers", encoded size sixteen,
12//! alignment eight.
13//!
14//! Rust has no stable `f128`, and every serialiser in this project used
15//! to answer that by writing a `double` and eight zero bytes: the right
16//! length and the wrong value, in silence. This crate is the answer
17//! instead. A wire runtime does not need to *compute* with a quadruple —
18//! it needs to carry one exactly, compare it, and read and write it as
19//! text. Those are bit manipulation and long division, not research.
20//!
21//! ## What is here
22//!
23//! - [`Float128`] — the value, one `u128` of IEEE 754 binary128 pattern.
24//! - Lossless sixteen-byte round trip in both byte orders.
25//! - Exact conversion from `f32`, `f64` and the integer types, and back
26//! with the inexact cases *reported* rather than rounded in silence.
27//! - IEEE comparison, and [`Float128::total_cmp`] for the places that
28//! need a total order — a key holder, a sorted expectation.
29//! - Decimal parsing and formatting that round-trips, so a JSON value
30//! file can carry one.
31//! - [`x87`] — the 80-bit extended format, because two of the four DDS
32//! vendors put *that* on the wire on x86 and a type that knows only
33//! the conformant form cannot read what the field actually sends.
34//!
35//! ## What is not here
36//!
37//! Arithmetic. `Add`, `Sub`, `Mul`, `Div` and `sqrt` are not
38//! implemented; `docs/float128-column.md` §6 says what they would take.
39//! Nothing in the wire path needs them, and a half-correct `Add` is
40//! worse than none.
41//!
42//! ## Spec
43//!
44//! - CORBA 3.3 part 2 §9.3.1.1 (alignment) and §9.3.1.3 with Figure 9.2
45//! (the bit layout, and the whole-sixteen-byte order reversal).
46//! - DDS-XTypes 1.3 §7.4.1.1.1 Table 31 (size sixteen, alignment eight)
47//! and §7.4.3.2.2 `MAXALIGN` (four under XCDR2).
48//! - IEEE 754-2008 clause 3.6 for binary128 itself.
49//!
50//! ## Layer position
51//!
52//! Layer 0. Depends on nothing.
53#![no_std]
54#![forbid(unsafe_code)]
55
56extern crate alloc;
57
58#[cfg(test)]
59extern crate std;
60
61mod bigint;
62mod cmp;
63mod convert;
64mod decimal;
65mod float;
66pub mod x87;
67
68pub use convert::Inexact;
69pub use decimal::ParseFloat128Error;
70pub use float::{Class, Float128};