use crate::common::f_fmla;
use crate::polyeval::f_polyeval5;
use crate::sin_cosf::sincosf_eval::sincosf_eval;
pub fn f_sincf(x: f32) -> f32 {
let x_abs = x.to_bits() & 0x7fff_ffffu32;
let xd = x as f64;
if x_abs <= 0x3e49_0fdbu32 {
if x_abs < 0x39e8_9769u32 {
if x_abs == 0u32 {
return 1.;
}
return f_fmla(
xd * xd,
f64::from_bits(0xbfc555555265f618),
f64::from_bits(0x3ff0000000000000),
) as f32;
}
let xsqr = xd * xd;
let p = f_polyeval5(
xsqr,
f64::from_bits(0x3ff0000000000000),
f64::from_bits(0xbfc55555555554c6),
f64::from_bits(0x3f81111111085e65),
f64::from_bits(0xbf2a019f70fb4d4f),
f64::from_bits(0x3ec718d179815e74),
);
return p as f32;
}
if x_abs >= 0x7f80_0000u32 {
return x + f32::NAN;
}
let rs = sincosf_eval(xd, x_abs);
let v_sin = f_fmla(rs.sin_y, rs.cos_k, f_fmla(rs.cosm1_y, rs.sin_k, rs.sin_k));
(v_sin / xd) as f32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_f_sincf() {
assert_eq!(f_sincf(-7.991783e37), -1.1754942946874968e-38);
assert_eq!(f_sincf(-8.04695e37), 1.1754942974913884e-38);
assert_eq!(f_sincf(-0.00044236073), 0.9999999673861641);
assert_eq!(f_sincf(0.0), 1.0);
assert_eq!(f_sincf(0.2), 0.99334663);
assert!(f_sincf(f32::INFINITY).is_nan());
assert!(f_sincf(f32::NEG_INFINITY).is_nan());
}
}