Skip to main content

emit_oracle_input/
emit_oracle_input.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 ZeroDDS Contributors
3//! Writes the oracle's input: bit patterns, and what this crate prints
4//! for them.
5//!
6//! `crates/float128/tests/oracle/README.md` is the procedure. The output
7//! goes to `tests/oracle/patterns.txt` and is checked in, so the oracle
8//! run on the Linux host and the test that compares against it are
9//! looking at the same values a year from now.
10//!
11//! ```sh
12//! cargo run -p zerodds-float128 --example emit_oracle_input \
13//!     > crates/float128/tests/oracle/patterns.txt
14//! ```
15#![allow(clippy::print_stdout)]
16
17use zerodds_float128::Float128;
18
19/// The same generator the tests use, so the corner cases and the random
20/// ones come from one place.
21struct Xorshift(u64);
22
23impl Xorshift {
24    fn next_u64(&mut self) -> u64 {
25        let mut x = self.0;
26        x ^= x << 13;
27        x ^= x >> 7;
28        x ^= x << 17;
29        self.0 = x;
30        x
31    }
32}
33
34fn main() {
35    let named = [
36        Float128::ZERO,
37        Float128::NEG_ZERO,
38        Float128::ONE,
39        Float128::NEG_ONE,
40        Float128::MAX,
41        Float128::MIN,
42        Float128::MIN_POSITIVE,
43        Float128::MIN_SUBNORMAL,
44        Float128::EPSILON,
45        Float128::from_bits(Float128::ONE.to_bits() + 1),
46        Float128::from_bits(Float128::MIN_POSITIVE.to_bits() - 1),
47        Float128::from_f64(1.5),
48        Float128::from_f64(-2.75),
49        Float128::from_f64(0.1),
50        Float128::from_f64(f64::MAX),
51        Float128::from_f64(f64::MIN_POSITIVE),
52        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 52)),
53        Float128::from_bits(Float128::ONE.to_bits() | (1u128 << 12)),
54    ];
55    let mut rng = Xorshift(0x0aac_1e50_dead_beef);
56    let mut patterns: Vec<Float128> = named.to_vec();
57    for _ in 0..500 {
58        let bits = (u128::from(rng.next_u64()) << 64) | u128::from(rng.next_u64());
59        // Finite only: quadmath prints `inf` and `nan` without digits,
60        // and those cases are pinned by name in the unit tests instead.
61        let exponent = u128::from(rng.next_u64() as u16 % 0x7fff) << 112;
62        patterns.push(Float128::from_bits(
63            (bits & !(0x7fffu128 << 112)) | exponent,
64        ));
65    }
66    for value in patterns {
67        println!("{:032x} {}", value.to_bits(), value.to_shortest_decimal());
68    }
69}