use crate::double_double::DoubleDouble;
use crate::dyadic_float::{DyadicFloat128, DyadicSign};
use crate::polyeval::f_polyeval9;
#[inline]
pub(crate) fn bessel_0_asympt_beta(recip: DoubleDouble) -> DoubleDouble {
const C: [(u64, u64); 10] = [
(0x0000000000000000, 0x3ff0000000000000),
(0x0000000000000000, 0xbfb0000000000000),
(0x0000000000000000, 0x3fba800000000000),
(0x0000000000000000, 0xbfe15f0000000000),
(0x0000000000000000, 0x4017651180000000),
(0x0000000000000000, 0xc05ab8c13b800000),
(0x0000000000000000, 0x40a730492f262000),
(0x0000000000000000, 0xc0fc73a7acd696f0),
(0xbdf3a00000000000, 0x41577458dd9fce68),
(0xbe4ba6b000000000, 0xc1b903ab9b27e18f),
];
let x2 = DoubleDouble::quick_mult(recip, recip);
let mut p = DoubleDouble::mul_add(
x2,
DoubleDouble::from_bit_pair(C[9]),
DoubleDouble::from_bit_pair(C[8]),
);
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[7].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[6].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[5].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[4].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[3].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[2].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[1].1));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[0].1));
p
}
#[inline]
pub(crate) fn bessel_0_asympt_beta_fast(recip: DoubleDouble) -> DoubleDouble {
const C: [u64; 10] = [
0x3ff0000000000000,
0xbfb0000000000000,
0x3fba800000000000,
0xbfe15f0000000000,
0x4017651180000000,
0xc05ab8c13b800000,
0x40a730492f262000,
0xc0fc73a7acd696f0,
0x41577458dd9fce68,
0xc1b903ab9b27e18f,
];
let x2 = DoubleDouble::quick_mult(recip, recip);
let p = f_polyeval9(
x2.hi,
f64::from_bits(C[1]),
f64::from_bits(C[2]),
f64::from_bits(C[3]),
f64::from_bits(C[4]),
f64::from_bits(C[5]),
f64::from_bits(C[6]),
f64::from_bits(C[7]),
f64::from_bits(C[8]),
f64::from_bits(C[9]),
);
DoubleDouble::mul_f64_add_f64(x2, p, f64::from_bits(C[0]))
}
pub(crate) fn bessel_0_asympt_beta_hard(recip: DyadicFloat128) -> DyadicFloat128 {
static C: [DyadicFloat128; 12] = [
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -127,
mantissa: 0x80000000_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -131,
mantissa: 0x80000000_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -131,
mantissa: 0xd4000000_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -128,
mantissa: 0x8af80000_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -125,
mantissa: 0xbb288c00_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -121,
mantissa: 0xd5c609dc_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -116,
mantissa: 0xb9824979_31000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -111,
mantissa: 0xe39d3d66_b4b78000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -105,
mantissa: 0xbba2c6ec_fe733d8c_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -99,
mantissa: 0xc81d5cd9_3f0c79ba_6b000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -92,
mantissa: 0x86118ddf_c1ffc100_0ee1b000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -86,
mantissa: 0xdc7ccfa9_930b874d_52df3464_00000000_u128,
},
];
let x2 = recip * recip;
let mut p = C[11];
for i in (0..11).rev() {
p = x2 * p + C[i];
}
p
}