#![allow(clippy::indexing_slicing)]
#![allow(clippy::excessive_precision)]
#![allow(clippy::approx_constant)]
#![allow(clippy::eq_op)]
use crate::Real;
static T: [Real; 13] = [
Real::from_bits(0x3fd5555555555563),
Real::from_bits(0x3fc111111110fe7a),
Real::from_bits(0x3faba1ba1bb341fe),
Real::from_bits(0x3f9664f48406d637),
Real::from_bits(0x3f8226e3e96e8493),
Real::from_bits(0x3f6d6d22c9560328),
Real::from_bits(0x3f57dbc8fee08315),
Real::from_bits(0x3f4344d8f2f26501),
Real::from_bits(0x3f3026f71a8d1068),
Real::from_bits(0x3f147e88a03792a6),
Real::from_bits(0x3f12b80f32f0a7e9),
Real::from_bits(0xbef375cbdb605373),
Real::from_bits(0x3efb2a7074bf7ad4),
];
const ONE: Real = Real::from_bits(0x3ff0000000000000);
const TWO: Real = Real::from_bits(0x4000000000000000);
const PIO4: Real = Real::from_bits(0x3fe921fb54442d18);
const PIO4_LO: Real = Real::from_bits(0x3c81a62633145c07);
pub(crate) const fn k_tan(mut x: Real, mut y: Real, odd: i32) -> Real {
let hx = (Real::to_bits(x) >> 32) as u32;
let big = (hx & 0x7fffffff) >= 0x3fe59428;
if big {
let sign = hx >> 31;
if sign != 0 {
x = -x;
y = -y;
}
x = (PIO4 - x) + (PIO4_LO - y);
y = Real::from_bits(0);
}
let z = x * x;
let w = z * z;
let r = T[1] + w * (T[3] + w * (T[5] + w * (T[7] + w * (T[9] + w * T[11]))));
let v = z * (T[2] + w * (T[4] + w * (T[6] + w * (T[8] + w * (T[10] + w * T[12])))));
let s = z * x;
let r = y + z * (s * (r + v) + y) + s * T[0];
let w = x + r;
if big {
let sign = hx >> 31;
let s_val = if odd == 0 { ONE } else { ONE - TWO };
let tmp = r - (w * w / (w + s_val));
let v = s_val - TWO * (x + tmp);
return if sign != 0 { -v } else { v };
}
if odd == 0 {
return w;
}
let w0 = zero_low_word(w);
let v = r - (w0 - x);
let a = -ONE / w;
let a0 = zero_low_word(a);
a0 + a * (ONE + a0 * w0 + a0 * v)
}
#[inline]
const fn zero_low_word(x: Real) -> Real {
Real::from_bits(Real::to_bits(x) & 0xffff_ffff_0000_0000)
}