1#![allow(clippy::indexing_slicing)]
2#![allow(clippy::excessive_precision)]
3#![allow(clippy::approx_constant)]
4#![allow(clippy::eq_op)]
5
6use crate::Real;
7
8const LN2_HI: Real = 6.93147180369123816490e-01; const LN2_LO: Real = 1.90821492927058770002e-10; const LG1: Real = 6.666666666666735130e-01; const LG2: Real = 3.999999999940941908e-01; const LG3: Real = 2.857142874366239149e-01; const LG4: Real = 2.222219843214978396e-01; const LG5: Real = 1.818357216161805012e-01; const LG6: Real = 1.531383769920937332e-01; const LG7: Real = 1.479819860511658591e-01; pub const fn log(mut x: Real) -> Real {
20 let x1p54 = Real::from_bits(0x4350000000000000); let mut ui = x.to_bits();
23 let mut hx: u32 = (ui >> 32) as u32;
24 let mut k: i32 = 0;
25
26 if (hx < 0x00100000) || ((hx >> 31) != 0) {
27 if ui << 1 == 0 {
29 return -1. / (x * x); }
31 if hx >> 31 != 0 {
32 return (x - x) / 0.0; }
34 k -= 54;
36 x *= x1p54;
37 ui = x.to_bits();
38 hx = (ui >> 32) as u32;
39 } else if hx >= 0x7ff00000 {
40 return x;
41 } else if hx == 0x3ff00000 && ui << 32 == 0 {
42 return 0.;
43 }
44
45 hx += 0x3ff00000 - 0x3fe6a09e;
47 k += ((hx >> 20) as i32) - 0x3ff;
48 hx = (hx & 0x000fffff) + 0x3fe6a09e;
49 ui = ((hx as u64) << 32) | (ui & 0xffffffff);
50 x = Real::from_bits(ui);
51
52 let f: Real = x - 1.0;
53 let hfsq: Real = 0.5 * f * f;
54 let s: Real = f / (2.0 + f);
55 let z: Real = s * s;
56 let w: Real = z * z;
57 let t1: Real = w * (LG2 + w * (LG4 + w * LG6));
58 let t2: Real = z * (LG1 + w * (LG3 + w * (LG5 + w * LG7)));
59 let r: Real = t2 + t1;
60 let dk: Real = k as Real;
61 s * (hfsq + r) + dk * LN2_LO - hfsq + f + dk * LN2_HI
62}