const ROUNDS_IN_HARDWARE: bool = !cfg!(any(
target_arch = "xtensa",
all(
any(target_arch = "x86", target_arch = "x86_64"),
not(target_feature = "sse4.1")
)
));
const WHOLE_FROM: f32 = 8_388_608.0;
#[inline(always)]
fn split(value: f32) -> Option<(f32, f32)> {
(value.abs() < WHOLE_FROM).then(|| {
let whole = (value as i32) as f32;
(whole, value - whole)
})
}
#[inline(always)]
pub fn floor(value: f32) -> f32 {
if ROUNDS_IN_HARDWARE {
return value.floor();
}
match split(value) {
Some((whole, fraction)) if fraction < 0.0 => whole - 1.0,
Some((whole, _)) => whole.copysign(value),
None => value,
}
}
#[inline(always)]
pub fn ceil(value: f32) -> f32 {
if ROUNDS_IN_HARDWARE {
return value.ceil();
}
match split(value) {
Some((whole, fraction)) if fraction > 0.0 => whole + 1.0,
Some((whole, _)) => whole.copysign(value),
None => value,
}
}
#[inline(always)]
pub fn round(value: f32) -> f32 {
if ROUNDS_IN_HARDWARE {
return value.round();
}
match split(value) {
Some((whole, fraction)) if fraction >= 0.5 => whole + 1.0,
Some((whole, fraction)) if fraction <= -0.5 => whole - 1.0,
Some((whole, _)) => whole.copysign(value),
None => value,
}
}