use crate::common::f_fmla;
use crate::double_double::DoubleDouble;
use crate::logs::{LOG_COEFFS, LOG_R_DD, LOG_RANGE_REDUCTION};
use crate::polyeval::f_polyeval4;
#[inline]
pub(crate) fn simple_fast_log(x: f64) -> f64 {
let x_u = x.to_bits();
const E_BIAS: u64 = (1u64 << (11 - 1u64)) - 1u64;
let mut x_e: i32 = -(E_BIAS as i32);
let shifted = (x_u >> 45) as i32;
let index = shifted & 0x7F;
let r = f64::from_bits(LOG_RANGE_REDUCTION[index as usize]);
x_e = x_e.wrapping_add(x_u.wrapping_add(1u64 << 45).wrapping_shr(52) as i32);
let e_x = x_e as f64;
const LOG_2_HI: f64 = f64::from_bits(0x3fe62e42fefa3800);
const LOG_2_LO: f64 = f64::from_bits(0x3d2ef35793c76730);
let log_r_dd = LOG_R_DD[index as usize];
let hi = f_fmla(e_x, LOG_2_HI, f64::from_bits(log_r_dd.1));
let lo = f_fmla(e_x, LOG_2_LO, f64::from_bits(log_r_dd.0));
let x_m = (x_u & 0x000F_FFFF_FFFF_FFFFu64) | 0x3FF0_0000_0000_0000u64;
let m = f64::from_bits(x_m);
let u;
#[cfg(any(
all(
any(target_arch = "x86", target_arch = "x86_64"),
target_feature = "fma"
),
target_arch = "aarch64"
))]
{
u = f_fmla(r, m, -1.0); }
#[cfg(not(any(
all(
any(target_arch = "x86", target_arch = "x86_64"),
target_feature = "fma"
),
target_arch = "aarch64"
)))]
{
use crate::logs::LOG_CD;
let c_m = x_m & 0x3FFF_E000_0000_0000u64;
let c = f64::from_bits(c_m);
u = f_fmla(r, m - c, f64::from_bits(LOG_CD[index as usize])); }
let r1 = DoubleDouble::from_exact_add(hi, u);
let u_sq = u * u;
let p0 = f_fmla(
u,
f64::from_bits(LOG_COEFFS[1]),
f64::from_bits(LOG_COEFFS[0]),
);
let p1 = f_fmla(
u,
f64::from_bits(LOG_COEFFS[3]),
f64::from_bits(LOG_COEFFS[2]),
);
let p2 = f_fmla(
u,
f64::from_bits(LOG_COEFFS[5]),
f64::from_bits(LOG_COEFFS[4]),
);
let p = f_polyeval4(u_sq, lo + r1.lo, p0, p1, p2);
r1.hi + p
}