use crate::common::f_fmla;
use crate::polyeval::f_polyeval5;
use crate::sin_cosf::sincosf_eval::sincosf_eval;
pub fn f_sinmxf(x: f32) -> f32 {
let x_abs = x.to_bits() & 0x7fff_ffffu32;
let xd = x as f64;
let ax: u32 = x.to_bits().wrapping_shl(1);
if ax == 0 || ax >= 0xffu32 << 24 {
if x_abs == 0u32 {
return x;
}
return f32::NAN; }
if x_abs <= 0x3e49_0fdbu32 {
if x_abs < 0x39e8_9769u32 {
let dx = x as f64;
let x2 = dx * dx;
let c = f_fmla(
x2,
f64::from_bits(0x3f81111111111111),
f64::from_bits(0xbfc5555555555555),
) * x2;
return (c * dx) as f32;
}
let xsqr = xd * xd;
let p = f_polyeval5(
xsqr,
f64::from_bits(0xbb8f6a339382f07f),
f64::from_bits(0xbfc5555555555545),
f64::from_bits(0x3f811111110ddf5c),
f64::from_bits(0xbf2a019fb330c620),
f64::from_bits(0x3ec719bc2a614884),
);
return (xd * p) as f32;
}
let rs = sincosf_eval(xd, x_abs);
let sinx = f_fmla(rs.sin_y, rs.cos_k, f_fmla(rs.cosm1_y, rs.sin_k, rs.sin_k));
(sinx - xd) as f32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn f_sinf_test() {
assert_eq!(f_sinmxf(0.00016344387), -0.00000000000072770376);
assert_eq!(f_sinmxf(0.0), 0.0);
assert_eq!(f_sinmxf(-0.0), 0.0);
assert_eq!(f_sinmxf(1.0), -0.15852901);
assert_eq!(f_sinmxf(0.3), -0.004479794);
assert_eq!(f_sinmxf(-1.0), 0.15852901);
assert_eq!(f_sinmxf(-0.3), 0.004479794);
assert_eq!(f_sinmxf(std::f32::consts::PI / 2.), -0.5707964);
assert!(f_sinmxf(f32::INFINITY).is_nan());
assert!(f_sinmxf(f32::NEG_INFINITY).is_nan());
assert!(f_sinmxf(f32::NAN).is_nan());
}
}