#![allow(dead_code)]
#[inline]
#[must_use]
pub fn abs32(n: f32) -> f32 {
let mask: u32 = 0x7FFF_FFFF;
let bits: u32 = n.to_bits() & mask;
f32::from_bits(bits)
}
#[inline]
#[must_use]
pub fn abs64(n: f64) -> f64 {
let mask: u64 = 0x7FFF_FFFF_FFFF_FFFF;
let bits: u64 = n.to_bits() & mask;
f64::from_bits(bits)
}
#[inline]
#[must_use]
pub fn floor32(n: f32) -> f32 {
const EPSILON32: f32 = 1e-6;
let mut result = trunc32(n);
if n.is_sign_negative() && abs32(n - result) > EPSILON32 {
result -= 1.0;
}
result
}
#[inline]
#[must_use]
pub fn floor64(n: f64) -> f64 {
const EPSILON64: f64 = 1e-12;
let mut result = trunc64(n);
if n.is_sign_negative() && abs64(n - result) > EPSILON64 {
result -= 1.0;
}
result
}
#[inline]
#[must_use]
pub fn powi32(n: f32, p: i32) -> f32 {
match p {
0 => 1.0,
1.. => {
let mut result = n;
for _i in 1..p {
result *= n;
}
result
}
_ => {
let mut result = n;
for _i in 1..p.abs() {
result /= n;
}
result
}
}
}
#[inline]
#[must_use]
pub fn powi64(n: f64, p: i32) -> f64 {
match p {
0 => 1.0,
1.. => {
let mut result = n;
for _i in 1..p {
result *= n;
}
result
}
_ => {
let mut result = n;
for _i in 1..p.abs() {
result /= n;
}
result
}
}
}
#[inline]
#[must_use]
pub fn round_half_away32(n: f32) -> f32 {
let bits = n.to_bits();
#[allow(clippy::cast_possible_wrap)]
let exponent = ((bits >> 23) & 0xFF) as i32 - 127;
if exponent < 0 {
if n.is_sign_positive() {
0.0
} else {
-0.0
}
} else if exponent < 23 {
let mask = (1u32 << (23 - exponent)) - 1;
let frac_part = bits & mask;
let half = 1u32 << (22 - exponent);
if frac_part >= half {
#[allow(clippy::cast_precision_loss)]
floor32(n + (half as f32 * powi32(2.0, -23)))
} else {
floor32(n)
}
} else {
n
}
}
#[inline]
#[must_use]
pub fn round_half_away64(n: f64) -> f64 {
let bits = n.to_bits();
let exponent = ((bits >> 52) & 0x7FF) as i32 - 1023;
if exponent < 0 {
if n.is_sign_positive() {
0.0
} else {
-0.0
}
} else if exponent < 52 {
let mask = (1u64 << (52 - exponent)) - 1;
let frac_part = bits & mask;
let half = 1u64 << (51 - exponent);
if frac_part >= half {
#[allow(clippy::cast_precision_loss)]
floor64(n + (half as f64 * powi64(2.0, -52)))
} else {
floor64(n)
}
} else {
n
}
}
#[inline]
#[must_use]
pub fn round_half_even32(n: f32) -> f32 {
let rounded = round_half_away32(n);
if rounded % 2.0 == 0.0 || abs32(rounded - n) > 0.5 {
rounded
} else {
rounded - signum32(n)
}
}
#[inline]
#[must_use]
pub fn round_half_even64(n: f64) -> f64 {
let rounded = round_half_away64(n);
if rounded % 2.0 == 0.0 || abs64(rounded - n) > 0.5 {
rounded
} else {
rounded - signum64(n)
}
}
#[inline]
#[must_use]
pub fn trunc32(n: f32) -> f32 {
let bits = n.to_bits();
#[allow(clippy::cast_possible_wrap)]
let exponent = ((bits >> 23) & 0xFF) as i32 - 127;
if exponent < 0 {
if n.is_sign_positive() {
0.0
} else {
-0.0
}
} else if exponent < 23 {
let mask = !((1u32 << (23 - exponent)) - 1);
let new_bits = bits & mask;
f32::from_bits(new_bits)
} else {
n
}
}
#[inline]
#[must_use]
pub fn trunc64(n: f64) -> f64 {
let bits = n.to_bits();
let exponent = ((bits >> 52) & 0x7FF) as i32 - 1023;
if exponent < 0 {
if n.is_sign_positive() {
0.0
} else {
-0.0
}
} else if exponent < 52 {
let mask = !((1u64 << (52 - exponent)) - 1);
let new_bits = bits & mask;
f64::from_bits(new_bits)
} else {
n
}
}
#[inline]
#[must_use]
pub fn signum32(n: f32) -> f32 {
let sign_bit = n.to_bits() >> 31;
if n.is_nan() {
f32::NAN
} else if sign_bit == 0 {
1.0
} else {
-1.0
}
}
#[inline]
#[must_use]
pub fn signum64(n: f64) -> f64 {
let sign_bit = n.to_bits() >> 63;
if n.is_nan() {
f64::NAN
} else if sign_bit == 0 {
1.0
} else {
-1.0
}
}
#[must_use]
pub fn sqrt_nr32(n: f32) -> f32 {
const EPSILON: f32 = 1e-7;
let mut x = n;
let mut x_next = 0.5 * (x + n / x);
while abs32(x - x_next) > EPSILON {
x = x_next;
x_next = 0.5 * (x + n / x);
}
x_next
}
#[must_use]
pub fn sqrt_nr64(n: f64) -> f64 {
const EPSILON: f64 = 1e-15;
let mut x = n;
let mut x_next = 0.5 * (x + n / x);
while abs64(x - x_next) > EPSILON {
x = x_next;
x_next = 0.5 * (x + n / x);
}
x_next
}
#[inline]
#[must_use]
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
pub fn sqrt_fisr32(n: f32) -> f32 {
let mut i: i32 = n.to_bits() as i32;
let threehalfs: f32 = 1.5;
let x2 = n * 0.5;
let mut y: f32;
i = 0x5f37_59df - (i >> 1); y = f32::from_bits(i as u32);
y = y * (threehalfs - (x2 * y * y));
1.0 / y
}
#[inline]
#[must_use]
#[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)]
pub fn sqrt_fisr64(n: f64) -> f64 {
let mut i: i64 = n.to_bits() as i64;
let three_halfs: f64 = 1.5;
let x2 = n * 0.5;
let mut y: f64;
i = 0x5fe6_eb50_c7b5_37a9 - (i >> 1); y = f64::from_bits(i as u64);
y = y * (three_halfs - (x2 * y * y));
1.0 / y
}