pub fn about_eq(a: f32, b: f32, epsilon: f32) -> bool {
if a.is_nan() {
b.is_nan()
} else if a.is_infinite() {
b.is_infinite() && a.is_sign_positive() == b.is_sign_positive()
} else {
(a - b).abs() < epsilon
}
}
pub fn about_eq_hash<H: std::hash::Hasher>(f: f32, epsilon: f32, state: &mut H) {
let (group, f) = if f.is_nan() {
(0u8, 0u64)
} else if f.is_infinite() {
(1, if f.is_sign_positive() { 1 } else { 2 })
} else {
let inv_epsilon = if epsilon > EQ_EPSILON_100 { 100000.0 } else { 100.0 };
(2, ((f as f64) * inv_epsilon) as u64)
};
use std::hash::Hash;
group.hash(state);
f.hash(state);
}
pub fn about_eq_ord(a: f32, b: f32, epsilon: f32) -> std::cmp::Ordering {
if about_eq(a, b, epsilon) {
std::cmp::Ordering::Equal
} else if a > b {
std::cmp::Ordering::Greater
} else {
std::cmp::Ordering::Less
}
}
pub const EQ_EPSILON: f32 = 0.00001;
pub const EQ_EPSILON_100: f32 = 0.001;