use super::{F32Like, LikeF32};
use crate::generic::scalbn_medium;
use crate::traits::FloatConsts;
const FRAC_PI_2_HI: u32 = 0x3FC90E00; const FRAC_PI_2_HIEX: u32 = 0x386D5111; const FRAC_PI_2_MI: u32 = 0x386D5000; const FRAC_PI_2_MIEX: u32 = 0x30885A31; const FRAC_PI_2_LO: u32 = 0x30885A00; const FRAC_PI_2_LOEX: u32 = 0x27C234C5;
impl<F: F32Like + FloatConsts> crate::generic::ReducePi2<LikeF32> for F {
#[inline]
fn frac_pi_2_hi() -> Self {
Self::from_raw(FRAC_PI_2_HI)
}
#[inline]
fn frac_pi_2_hiex() -> Self {
Self::from_raw(FRAC_PI_2_HIEX)
}
#[inline]
fn frac_pi_2_mi() -> Self {
Self::from_raw(FRAC_PI_2_MI)
}
#[inline]
fn frac_pi_2_miex() -> Self {
Self::from_raw(FRAC_PI_2_MIEX)
}
#[inline]
fn frac_pi_2_lo() -> Self {
Self::from_raw(FRAC_PI_2_LO)
}
#[inline]
fn frac_pi_2_loex() -> Self {
Self::from_raw(FRAC_PI_2_LOEX)
}
fn max_reduce_pi_2_medium() -> Self {
F::cast_from((1u32 << 9) - 1) * Self::frac_pi_2()
}
const REDUCE_PI_2_MEDIUM_TH1: i16 = 8;
const REDUCE_PI_2_MEDIUM_TH2: i16 = 20;
type SrcChunks = [u32; 1];
fn reduce_pi_2_prepare(x: Self) -> ([u32; 1], i16, usize) {
let mant = x.mant();
let x_chunks = [mant];
let e0 = x.exponent() - 23;
let jk = 3;
(x_chunks, e0, jk)
}
fn reduce_pi_2_compress(qp: &[u64; 20], qe: i16, ih: u32, jz: usize) -> (Self, Self) {
let mut iw = 0;
for &qp_i in qp[0..=jz].iter().rev() {
iw = (iw >> 24) + (qp_i << 6);
}
let fw0 = Self::cast_from((iw as u32) & 0xFFFFFF);
let fw1 = Self::cast_from(((iw >> 24) as u32) & 0xFFFFFF) * Self::exp2i_fast(24);
let fw2 = Self::cast_from((iw >> 48) as u32) * Self::exp2i_fast(48);
let mut y0 = ((fw0 + fw1) + fw2).purify();
let mut y1 = ((fw2 - y0) + fw1) + fw0;
let scale = i32::from(qe) - 6;
y0 = scalbn_medium(y0, scale);
y1 = scalbn_medium(y1, scale);
if ih == 0 {
(y0, y1)
} else {
(-y0, -y1)
}
}
}