use crate::double_double::DoubleDouble;
use crate::dyadic_float::{DyadicFloat128, DyadicSign};
use crate::polyeval::f_polyeval9;
#[inline]
pub(crate) fn bessel_1_asympt_alpha_fast(recip: DoubleDouble) -> DoubleDouble {
const C: [u64; 12] = [
0xbfd8000000000000,
0x3fc5000000000000,
0xbfd7bccccccccccd,
0x4002f486db6db6db,
0xc03e9fbf40000000,
0x4084997b55945d17,
0xc0d4a914195269d9,
0x412cd1b53816aec1,
0xc18aa4095d419351,
0x41ef809305f11b9d,
0xc2572e6809ed618b,
0x42c4c5b6057839f9,
];
let x2 = DoubleDouble::quick_mult(recip, recip);
let p = f_polyeval9(
x2.hi,
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]),
f64::from_bits(C[10]),
f64::from_bits(C[11]),
);
let mut z = DoubleDouble::mul_f64_add_f64(x2, p, f64::from_bits(C[2]));
z = DoubleDouble::mul_add_f64(x2, z, f64::from_bits(C[1]));
z = DoubleDouble::mul_add_f64(x2, z, f64::from_bits(C[0]));
DoubleDouble::quick_mult(z, recip)
}
#[inline]
pub(crate) fn bessel_1_asympt_alpha(recip: DoubleDouble) -> DoubleDouble {
const C: [(u64, u64); 12] = [
(0x0000000000000000, 0xbfd8000000000000),
(0x0000000000000000, 0x3fc5000000000000),
(0x3c6999999999999a, 0xbfd7bccccccccccd),
(0x3cab6db6db6db6db, 0x4002f486db6db6db),
(0x0000000000000000, 0xc03e9fbf40000000),
(0x3d21745d1745d174, 0x4084997b55945d17),
(0x3d789d89d89d89d9, 0xc0d4a914195269d9),
(0xbdb999999999999a, 0x412cd1b53816aec1),
(0xbdfe5a5a5a5a5a5a, 0xc18aa4095d419351),
(0x3e7e0ca50d79435e, 0x41ef809305f11b9d),
(0xbedff8b720000000, 0xc2572e6809ed618b),
(0xbf64e5d8ae68b7a7, 0x42c4c5b6057839f9),
];
let x2 = DoubleDouble::quick_mult(recip, recip);
let mut p = DoubleDouble::mul_add(
x2,
DoubleDouble::from_bit_pair(C[11]),
DoubleDouble::from_bit_pair(C[10]),
);
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[9]));
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[8]));
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[7]));
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[6]));
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[5]));
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[4]));
p = DoubleDouble::mul_add_f64(x2, p, f64::from_bits(C[3].1));
p = DoubleDouble::mul_add(x2, p, DoubleDouble::from_bit_pair(C[2]));
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));
let z = DoubleDouble::quick_mult(p, recip);
DoubleDouble::from_exact_add(z.hi, z.lo)
}
pub(crate) fn bessel_1_asympt_alpha_hard(reciprocal: DyadicFloat128) -> DyadicFloat128 {
static C: [DyadicFloat128; 18] = [
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -129,
mantissa: 0xc0000000_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -130,
mantissa: 0xa8000000_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -129,
mantissa: 0xbde66666_66666666_66666666_66666666_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -126,
mantissa: 0x97a436db_6db6db6d_b6db6db6_db6db6db_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -123,
mantissa: 0xf4fdfa00_00000000_00000000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -118,
mantissa: 0xa4cbdaac_a2e8ba2e_8ba2e8ba_2e8ba2e9_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -113,
mantissa: 0xa548a0ca_934ec4ec_4ec4ec4e_c4ec4ec5_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -108,
mantissa: 0xe68da9c0_b5760666_66666666_66666666_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -102,
mantissa: 0xd5204aea_0c9a8879_69696969_69696969_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -96,
mantissa: 0xfc04982f_88dce9e0_ca50d794_35e50d79_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -89,
mantissa: 0xb973404f_6b0c58ff_c5b90000_00000000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -82,
mantissa: 0xa62db02b_c1cfc563_44ea32e9_0b21642d_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -75,
mantissa: 0xb220e7ff_443c1584_7e85f4e0_55eb851f_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -68,
mantissa: 0xe10a255c_ca5e68cc_00c2d6c0_acdc8000_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -60,
mantissa: 0xa573790c_5186f23b_5db502ea_d9fa5432_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -52,
mantissa: 0x8c0ffedc_407a7015_453df84e_9c3f1d39_u128,
},
DyadicFloat128 {
sign: DyadicSign::Neg,
exponent: -44,
mantissa: 0x874226ed_c298a17a_d8c49a4e_dc9281a5_u128,
},
DyadicFloat128 {
sign: DyadicSign::Pos,
exponent: -36,
mantissa: 0x93cab36c_9ab9495c_310fa9cd_4b065359_u128,
},
];
let x2 = reciprocal * reciprocal;
let mut p = C[17];
for i in (0..17).rev() {
p = x2 * p + C[i];
}
p * reciprocal
}