Skip to main content

thermite_compensated/specialized/special/
ps.rs

1//! Double-single: `Compensated<V>` over an `f32` element, ~48 bits of mantissa.
2//!
3//! Named after `thermite-special`'s `ps.rs`, and for the same reason - this is the
4//! `f32`-element half of the per-width split.
5//!
6//! Empty, so every method takes the generic Stirling/Bernoulli default from
7//! [`super`]. Two things would justify filling it in, neither of them urgent:
8//!
9//! - ~48 bits is inside `lanczos13m53`'s range, so the coefficients `thermite-special`
10//!   already ships as `LANCZOS_F64` would serve here if re-expressed as
11//!   `Compensated<f32>` constants - trading the shift loop for a table it already owns.
12//! - The Bernoulli series needs about half as many terms at this width as at
13//!   double-double, which the default's term count should derive rather than assume.
14
15use thermite::prelude::*;
16
17use super::SpecializedCompensatedSpecialMath;
18use crate::Compensated;
19
20impl<V: FloatVector<Element = f32>> SpecializedCompensatedSpecialMath<f32> for V {
21    const INV_LANGEVIN_STEPS: usize = 2;
22
23    #[inline(always)]
24    fn dd_const(hi: f64, _lo: f64) -> Compensated<Self> {
25        // ~48 bits wanted, `hi` carries 53: `lo` is far below this width.
26        let c = Compensated::<f32>::from_f64(hi);
27        Compensated {
28            value: Self::splat(c.value),
29            error: Self::splat(c.error),
30        }
31    }
32}
Last built: 2026-09-08 21:35:55 UTC