use core::f64::consts::FRAC_PI_2;
use crate::soft_f64::F64;
use super::{
helpers::{k_cosf, k_sinf, rem_pio2f},
F32,
};
const C1_PIO2: F64 = f64!(1.).mul(f64!(FRAC_PI_2));
const C2_PIO2: F64 = f64!(2.).mul(f64!(FRAC_PI_2));
const C3_PIO2: F64 = f64!(3.).mul(f64!(FRAC_PI_2));
const C4_PIO2: F64 = f64!(4.).mul(f64!(FRAC_PI_2));
pub const fn cos(x: F32) -> F32 {
let x64 = x.to_f64();
let x1p120 = F32::from_bits(0x7b800000);
let mut ix = x.to_bits();
let sign = (ix >> 31) != 0;
ix &= 0x7fffffff;
if ix <= 0x3f490fda {
if ix < 0x39800000 {
let _ = x.add(x1p120);
return f32!(1.0);
}
return k_cosf(x64);
}
if ix <= 0x407b53d1 {
if ix > 0x4016cbe3 {
return k_cosf(if sign {
x64.add(C2_PIO2)
} else {
x64.sub(C2_PIO2)
})
.neg();
} else if sign {
return k_sinf(x64.add(C1_PIO2));
} else {
return k_sinf(C1_PIO2.sub(x64));
}
}
if ix <= 0x40e231d5 {
if ix > 0x40afeddf {
return k_cosf(if sign {
x64.add(C4_PIO2)
} else {
x64.sub(C4_PIO2)
});
} else if sign {
return k_sinf(x64.neg().sub(C3_PIO2));
} else {
return k_sinf(x64.sub(C3_PIO2));
}
}
if ix >= 0x7f800000 {
return x.sub(x);
}
let (n, y) = rem_pio2f(x);
match n & 3 {
0 => k_cosf(y),
1 => k_sinf(y.neg()),
2 => k_cosf(y).neg(),
_ => k_sinf(y),
}
}