use crate::common::f_fmla;
use crate::polyeval::f_polyeval5;
#[inline]
pub fn f_cotf(x: f32) -> f32 {
let x_abs = x.to_bits() & 0x7fff_ffffu32;
let xd = x as f64;
if x_abs <= 0x3dc9_0fdbu32 {
if x_abs < 0x3980_0000u32 {
if x_abs == 0 {
return 1. / x;
}
let ddx = x as f64;
let dx = 1. / ddx;
return f_fmla(ddx, f64::from_bits(0xbfd5555555555555), dx) as f32;
}
let xsqr = xd * xd;
let p = f_polyeval5(
xsqr,
f64::from_bits(0x3ff0000000000000),
f64::from_bits(0xbfd5555555555466),
f64::from_bits(0xbf96c16c16fb8937),
f64::from_bits(0xbf6156688756cd43),
f64::from_bits(0xbf2bce669d7cd742),
);
return (p / xd) as f32;
}
if x_abs >= 0x7f80_0000u32 {
return x + f32::NAN;
}
let rs = crate::tangent::evalf::tanf_eval(xd, x_abs);
let num = rs.tan_y + rs.tan_k;
let den = f_fmla(rs.tan_y, -rs.tan_k, 1.);
(den / num) as f32
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cotf_test() {
assert_eq!(f_cotf(0.0010348097), 966.36084);
assert_eq!(f_cotf(0.0020286469), 492.93872);
assert_eq!(f_cotf(-0.0020286469), -492.93872);
assert_eq!(f_cotf(1.0020286469), 0.63923126);
assert_eq!(f_cotf(-1.0020286469), -0.63923126);
assert_eq!(f_cotf(0.0), f32::INFINITY);
assert_eq!(f_cotf(-0.0), f32::NEG_INFINITY);
assert!(f_cotf(f32::INFINITY).is_nan());
assert!(f_cotf(f32::NEG_INFINITY).is_nan());
assert!(f_cotf(f32::NAN).is_nan());
}
}