deep_time/math/
rem_pio2.rs1#![allow(clippy::indexing_slicing)]
2#![allow(clippy::excessive_precision)]
3#![allow(clippy::approx_constant)]
4#![allow(clippy::eq_op)]
5
6use super::rem_pio2_large;
19use crate::Real;
20
21const EPS: Real = 2.2204460492503131e-16;
24const TO_INT: Real = 1.5 / EPS;
29const INV_PIO2: Real = 6.36619772367581382433e-01; const PIO2_1: Real = 1.57079632673412561417e+00; const PIO2_1T: Real = 6.07710050650619224932e-11; const PIO2_2: Real = 6.07710050630396597660e-11; const PIO2_2T: Real = 2.02226624879595063154e-21; const PIO2_3: Real = 2.02226624871116645580e-21; const PIO2_3T: Real = 8.47842766036889956997e-32; pub(crate) const fn rem_pio2(x: Real) -> (i32, Real, Real) {
49 let x1p24 = Real::from_bits(0x4170000000000000);
50
51 let sign = (Real::to_bits(x) >> 63) as i32;
52 let ix = (Real::to_bits(x) >> 32) as u32 & 0x7fffffff;
53
54 const fn medium(x: Real, ix: u32) -> (i32, Real, Real) {
55 let tmp = x * INV_PIO2 + TO_INT;
56 let f_n = tmp - TO_INT;
57 let n = f_n as i32;
58 let mut r = x - f_n * PIO2_1;
59 let mut w = f_n * PIO2_1T;
60 let mut y0 = r - w;
61 let ui = Real::to_bits(y0);
62 let ey = (ui >> 52) as i32 & 0x7ff;
63 let ex = (ix >> 20) as i32;
64
65 if ex - ey > 16 {
66 let t = r;
67 w = f_n * PIO2_2;
68 r = t - w;
69 w = f_n * PIO2_2T - ((t - r) - w);
70 y0 = r - w;
71 let ey = (Real::to_bits(y0) >> 52) as i32 & 0x7ff;
72 if ex - ey > 49 {
73 let t = r;
74 w = f_n * PIO2_3;
75 r = t - w;
76 w = f_n * PIO2_3T - ((t - r) - w);
77 y0 = r - w;
78 }
79 }
80 let y1 = (r - y0) - w;
81 (n, y0, y1)
82 }
83
84 if ix <= 0x400f6a7a {
87 if (ix & 0xfffff) == 0x921fb {
89 return medium(x, ix);
90 }
91 return medium(x, ix);
93 }
94
95 if ix <= 0x401c463b {
96 if ix == 0x4012d97c || ix == 0x401921fb {
98 return medium(x, ix);
99 }
100 return medium(x, ix);
102 }
103
104 if ix < 0x413921fb {
105 return medium(x, ix);
107 }
108
109 if ix >= 0x7ff00000 {
111 let y0 = x - x;
112 let y1 = y0;
113 return (0, y0, y1);
114 }
115
116 let mut ui = Real::to_bits(x);
118 ui &= (!1) >> 12;
119 ui |= (0x3ff + 23) << 52;
120 let mut z = Real::from_bits(ui);
121
122 let mut tx = [0.0; 3];
123 let mut i: usize = 0;
124 while i < 2 {
125 tx[i] = z as i32 as Real;
126 z = (z - tx[i]) * x1p24;
127 i += 1;
128 }
129 tx[2] = z;
130
131 let mut i = 2;
132 while i != 0 && tx[i] == 0.0 {
133 i -= 1;
134 }
135
136 let mut ty = [0.0; 3];
137 let n = rem_pio2_large(&tx, i + 1, &mut ty, ((ix as i32) >> 20) - (0x3ff + 23), 1);
138
139 if sign != 0 {
140 return (-n, -ty[0], -ty[1]);
141 }
142 (n, ty[0], ty[1])
143}