#![allow(
clippy::disallowed_macros,
reason = "raw-helper: this module calls the platform f32/f64 max/min via crate::raw_minmax::raw_minmax_here!() at sites proven safe by nonzero-const:/both-abs:/int-cast: reasoning, see scripts/raw_minmax_manifest.toml"
)]
crate::raw_minmax::raw_minmax_here!(max_f32);
#[must_use]
pub fn agrees(a: f32, b: f32, rel_tol: f32) -> bool {
a.to_bits() == b.to_bits()
|| (a.is_nan() && b.is_nan())
|| (a.is_finite() && b.is_finite() && (a - b).abs()
<= rel_tol * raw_max_f32(raw_max_f32(a.abs(), b.abs(), crate::raw_minmax::Reason::BothAbs), 1.0, crate::raw_minmax::Reason::NonzeroConst))
}
#[cfg(test)]
mod tests {
use super::agrees;
#[test]
fn the_table() {
let (inf, nan) = (f32::INFINITY, f32::NAN);
for (a, b, want) in [
(inf, inf, true),
(-inf, -inf, true),
(inf, -inf, false),
(-inf, inf, false),
(inf, f32::MAX, false),
(f32::MAX, inf, false),
(nan, nan, true),
(nan, -nan, true),
(nan, 1.0, false),
(1.0, nan, false),
(nan, inf, false),
(-0.0, 0.0, true),
(0.0, -0.0, true),
(1.0, 1.0 + 1e-5, true),
(1.0, 1.001, false),
(1e6, 1e6 + 50.0, true),
(1e6, 1e6 + 200.0, false),
(1.0, 1.000_05, true),
(
f32::from_bits(0x4308_1874),
f32::from_bits(0x4308_1bf0),
true,
), (0.5, 2.0, false),
] {
assert_eq!(agrees(a, b, 1e-4), want, "{a} vs {b}");
assert_eq!(
agrees(b, a, 1e-4),
want,
"{b} vs {a} (the relation is symmetric)"
);
}
}
}