use crate::MAX_ABS_QUANTITY_POWER;
fn clamp_power(power: i64) -> i32 {
power.clamp(
-i64::from(MAX_ABS_QUANTITY_POWER),
i64::from(MAX_ABS_QUANTITY_POWER),
) as i32
}
pub fn saturating_power_add(lhs: i32, rhs: i32) -> i32 {
clamp_power(i64::from(lhs) + i64::from(rhs))
}
pub fn saturating_power_sub(lhs: i32, rhs: i32) -> i32 {
clamp_power(i64::from(lhs) - i64::from(rhs))
}
pub fn average_power(lhs: i32, rhs: i32) -> i32 {
let average = (i64::from(lhs) + i64::from(rhs)) / 2;
clamp_power(average)
}
pub fn canonicalize_quantity_parts(multiplier: f64, power: i32) -> (f64, i32) {
if multiplier == 0.0 {
return (0.0, 0);
}
if multiplier.is_nan() {
return (f64::NAN, 0);
}
if multiplier.is_infinite() {
return (multiplier, 0);
}
let power_on_multiplier = multiplier.abs().log10().round() as i32;
let normalized_multiplier = multiplier / 10_f64.powi(power_on_multiplier);
let normalized_power = saturating_power_add(power, power_on_multiplier);
if normalized_power <= -MAX_ABS_QUANTITY_POWER {
(0.0, 0)
} else if normalized_power >= MAX_ABS_QUANTITY_POWER {
if normalized_multiplier.is_sign_negative() {
(f64::NEG_INFINITY, 0)
} else {
(f64::INFINITY, 0)
}
} else {
(normalized_multiplier, normalized_power)
}
}
pub fn pow10_delta(lhs: i32, rhs: i32) -> f64 {
10_f64.powi(saturating_power_sub(lhs, rhs))
}