#[cfg(test)]
mod tests {
use fixed::types::{I4F12, I4F60, I8F8, I8F24, I16F16, I20F12, I24F8, I32F32, I48F16, I64F64};
use fixed_analytics::CordicNumber;
#[test]
#[allow(clippy::approx_constant, reason = "testing pi approximation")]
fn basic_operations_i16f16() {
let x = I16F16::from_num(2.5);
assert_eq!(I16F16::zero(), I16F16::ZERO);
assert_eq!(I16F16::one(), I16F16::ONE);
assert!(I16F16::pi() > I16F16::from_num(3.14));
assert!(I16F16::pi() < I16F16::from_num(3.15));
assert!(!x.is_negative());
assert!((-x).is_negative());
}
#[test]
fn generic_impl_works_for_various_types() {
let _: I8F24 = I8F24::pi();
let _: I8F24 = I8F24::frac_pi_2();
let _: I24F8 = I24F8::pi();
let _: I24F8 = I24F8::frac_pi_2();
let _: I4F12 = I4F12::pi();
let _: I20F12 = I20F12::pi();
let _: I48F16 = I48F16::pi();
let _: I4F60 = I4F60::pi();
}
#[test]
fn from_i1f63_across_types() {
let half_bits: i64 = 0x4000_0000_0000_0000;
let i8f8_half: f32 = I8F8::from_i1f63(half_bits).to_num();
assert!((i8f8_half - 0.5).abs() < 0.01);
let i16f16_half: f32 = I16F16::from_i1f63(half_bits).to_num();
assert!((i16f16_half - 0.5).abs() < 0.0001);
let i32f32_half: f64 = I32F32::from_i1f63(half_bits).to_num();
assert!((i32f32_half - 0.5).abs() < 1e-9);
let i64f64_half: f64 = I64F64::from_i1f63(half_bits).to_num();
assert!((i64f64_half - 0.5).abs() < 1e-15);
let i24f8_half: f32 = I24F8::from_i1f63(half_bits).to_num();
assert!((i24f8_half - 0.5).abs() < 0.01);
let i4f60_half: f64 = I4F60::from_i1f63(half_bits).to_num();
assert!((i4f60_half - 0.5).abs() < 1e-15);
}
#[test]
fn frac_bits_correct() {
assert_eq!(I8F8::frac_bits(), 8);
assert_eq!(I16F16::frac_bits(), 16);
assert_eq!(I32F32::frac_bits(), 32);
assert_eq!(I64F64::frac_bits(), 64);
assert_eq!(I8F24::frac_bits(), 24);
assert_eq!(I24F8::frac_bits(), 8);
assert_eq!(I4F12::frac_bits(), 12);
assert_eq!(I48F16::frac_bits(), 16);
}
#[test]
fn div_overflow_saturates_to_min() {
let neg = I16F16::from_num(-1);
let zero = I16F16::ZERO;
assert_eq!(neg.div(zero), I16F16::MIN);
}
#[test]
fn div_by_zero_positive_saturates_to_max() {
let pos = I16F16::from_num(1);
let zero = I16F16::ZERO;
assert_eq!(pos.div(zero), I16F16::MAX);
}
#[test]
fn frac_pi_4_values() {
let pi_4_16: f32 = I16F16::frac_pi_4().to_num();
assert!(
(pi_4_16 - core::f32::consts::FRAC_PI_4).abs() < 0.001,
"I16F16::frac_pi_4() = {pi_4_16}, expected ~0.7854"
);
let pi_4_32: f64 = I32F32::frac_pi_4().to_num();
assert!(
(pi_4_32 - core::f64::consts::FRAC_PI_4).abs() < 1e-9,
"I32F32::frac_pi_4() = {pi_4_32}, expected ~0.7854"
);
let pi_4_64: f64 = I64F64::frac_pi_4().to_num();
assert!(
(pi_4_64 - core::f64::consts::FRAC_PI_4).abs() < 1e-15,
"I64F64::frac_pi_4() = {pi_4_64}, expected ~0.7854"
);
}
}