zerodds-float128
IEEE 754 binary128 in software: the sixteen bytes CDR gives
long double, as a value type with exact conversions, IEEE comparison, and round-tripping decimal.
- Source: crates/float128
- API docs: docs.rs/zerodds-float128
use zerodds_float128::Float128;
// Sixteen bytes off the wire and sixteen back, unchanged.
let value = Float128::from_be_bytes(bytes);
assert_eq!(value.to_be_bytes(), bytes);
// A value a double can hold converts; one it cannot is refused by name.
let narrow: f64 = value.to_f64()?;
Why it exists
CORBA 3.3 part 2 §9.3.1.3 gives long double one sign bit, a fifteen-bit exponent and a 112-bit fraction, and DDS-XTypes 1.3 Table 31 names the result: quadruple precision, sixteen bytes, aligned to eight. Rust has no stable f128, so this project used to write a double and eight zero bytes for it — the right length, the wrong value, and no error. Carrying the value needs no arithmetic, only bit manipulation and long division.
What it does
- Lossless sixteen-byte round trip in both byte orders. CORBA Figure 9.2 reverses the whole sixteen bytes between orders, not two halves, and that is what RTI Connext was measured doing.
- Exact conversion from
f32,f64and the integers, and back with the inexact cases returned as anInexactcarrying the rounded value — never rounded in silence. - IEEE comparison, plus
total_cmpfor a@keymember and a sorted expectation, where aNonefor NaN is not an answer. - Decimal in and out, correctly rounded against the exact value, so a JSON value file can carry one.
to_shortest_decimalwrites the fewest digits that read back;to_exact_decimalwrites all of them. - The x87 80-bit extended format, in both directions, because Fast DDS and OpenDDS put that on the wire on x86-64 and a reader that only knows the conformant form cannot read the field.
What it does not do
Arithmetic. No Add, no Mul, no sqrt. Nothing on the wire path needs them and a half-correct one is worse than none; docs/float128-column.md §6 says what adding them would take and how it would be checked.
The oracle
tests/oracle/ holds values run through GCC's __float128, compared in both directions: their printer against this crate's parser, and their parser against this crate's printer. A crate that implements a format cannot be its own second opinion.
Position
- No dependency on another ZeroDDS crate.
- Used by
zerodds-wire,zerodds-wire-codecandzerodds-wire-probe.
zerodds-float128
IEEE 754 binary128 in Software: die sechzehn Bytes, die CDR einem
long doublegibt, als Werttyp mit exakten Umwandlungen, IEEE-Vergleich und Dezimaldarstellung, die sich verlustfrei zurücklesen lässt.
- Quelle: crates/float128
- API-Docs: docs.rs/zerodds-float128
use zerodds_float128::Float128;
// Sixteen bytes off the wire and sixteen back, unchanged.
let value = Float128::from_be_bytes(bytes);
assert_eq!(value.to_be_bytes(), bytes);
// A value a double can hold converts; one it cannot is refused by name.
let narrow: f64 = value.to_f64()?;
Warum es sie gibt
CORBA 3.3 Teil 2 §9.3.1.3 gibt long double ein Vorzeichenbit, einen Exponenten von fünfzehn Bit und eine Mantisse von 112 Bit, und DDS-XTypes 1.3 Tabelle 31 benennt das Ergebnis: vierfache Genauigkeit, sechzehn Bytes, auf acht ausgerichtet. Rust hat kein stabiles f128; dieses Projekt schrieb deshalb früher ein double und acht Nullbytes — die richtige Länge, der falsche Wert und kein Fehler. Den Wert zu transportieren braucht keine Arithmetik, nur Bitmanipulation und schriftliche Division.
Was sie tut
- Verlustfreier Roundtrip der sechzehn Bytes in beiden Bytereihenfolgen. CORBA Abbildung 9.2 kehrt beim Wechsel der Reihenfolge alle sechzehn Bytes um, nicht zwei Hälften, und so verhielt sich RTI Connext in der Messung.
- Exakte Umwandlung aus
f32,f64und den Ganzzahltypen und zurück; ungenaue Fälle kommen alsInexactmit dem gerundeten Wert zurück — nie stillschweigend gerundet. - IEEE-Vergleich, dazu
total_cmpfür einen@key-Member und eine sortierte Erwartung, wo einNonefür NaN keine Antwort ist. - Dezimalzahlen hinein und heraus, korrekt gerundet gegen den exakten Wert, damit eine JSON-Wertedatei einen solchen Wert tragen kann.
to_shortest_decimalschreibt die wenigsten Ziffern, die sich zurücklesen lassen;to_exact_decimalschreibt alle. - Das erweiterte 80-Bit-Format von x87, in beide Richtungen, weil Fast DDS und OpenDDS es auf x86-64 auf die Leitung legen und ein Reader, der nur die konforme Form kennt, das Feld nicht lesen kann.
Was sie nicht tut
Arithmetik. Kein Add, kein Mul, kein sqrt. Nichts auf dem Weg zur Leitung braucht sie, und eine halb richtige ist schlechter als keine; docs/float128-column.md §6 beschreibt, was es bräuchte, sie hinzuzufügen, und wie es geprüft würde.
Das Orakel
tests/oracle/ enthält Werte, die durch __float128 von GCC gelaufen sind, verglichen in beide Richtungen: deren Ausgabe gegen den Parser dieser Crate und deren Parser gegen die Ausgabe dieser Crate. Eine Crate, die ein Format implementiert, kann nicht ihre eigene zweite Meinung sein.
Stellung
- Keine Abhängigkeit von einer anderen ZeroDDS-Crate.
- Genutzt von
zerodds-wire,zerodds-wire-codecundzerodds-wire-probe.