pub const STABILITY_EPSILON_F32: f32 = 1e-7;
pub const STABILITY_EPSILON_F64: f64 = 1e-15;
pub const MAX_SAFE_VALUE_F32: f32 = 1e30;
pub const MAX_SAFE_VALUE_F64: f64 = 1e300;
pub fn is_stable_f32(x: f32) -> bool {
x.is_finite() && x.abs() < MAX_SAFE_VALUE_F32 && (x.abs() > STABILITY_EPSILON_F32 || x == 0.0)
}
pub fn is_stable_f64(x: f64) -> bool {
x.is_finite() && x.abs() < MAX_SAFE_VALUE_F64 && (x.abs() > STABILITY_EPSILON_F64 || x == 0.0)
}
pub fn stabilize_f32(x: f32) -> f32 {
if !x.is_finite() {
return 0.0;
}
if x.abs() > MAX_SAFE_VALUE_F32 {
x.signum() * MAX_SAFE_VALUE_F32
} else if x.abs() < STABILITY_EPSILON_F32 && x != 0.0 {
x.signum() * STABILITY_EPSILON_F32
} else {
x
}
}
pub fn stabilize_f64(x: f64) -> f64 {
if !x.is_finite() {
return 0.0;
}
if x.abs() > MAX_SAFE_VALUE_F64 {
x.signum() * MAX_SAFE_VALUE_F64
} else if x.abs() < STABILITY_EPSILON_F64 && x != 0.0 {
x.signum() * STABILITY_EPSILON_F64
} else {
x
}
}