25[[nodiscard]]
static inline constexpr f64
force25Bit(f64 x) {
26 u64 bits = std::bit_cast<u64>(x);
27 bits = (bits & 0xfffffffff8000000ULL) + (bits & 0x8000000);
28 return std::bit_cast<f64>(bits);
33[[nodiscard]]
static inline constexpr f32
fma(f32 x, f32 y, f32 z) {
34 return static_cast<f32
>(
static_cast<f64
>(x) *
static_cast<f64
>(y) +
static_cast<f64
>(z));
39[[nodiscard]]
static inline constexpr f32
fms(f32 x, f32 y, f32 z) {
40 return static_cast<f32
>(
static_cast<f64
>(x) *
static_cast<f64
>(y) -
static_cast<f64
>(z));
45 f32 sinVal, cosVal, sinDt, cosDt;
55 {0.000000f, 1.000000f, 0.024541f, -0.000301f},
56 {0.024541f, 0.999699f, 0.024526f, -0.000903f},
57 {0.049068f, 0.998795f, 0.024497f, -0.001505f},
58 {0.073565f, 0.997290f, 0.024453f, -0.002106f},
59 {0.098017f, 0.995185f, 0.024394f, -0.002705f},
60 {0.122411f, 0.992480f, 0.024320f, -0.003303f},
61 {0.146730f, 0.989177f, 0.024231f, -0.003899f},
62 {0.170962f, 0.985278f, 0.024128f, -0.004492f},
63 {0.195090f, 0.980785f, 0.024011f, -0.005083f},
64 {0.219101f, 0.975702f, 0.023879f, -0.005671f},
65 {0.242980f, 0.970031f, 0.023733f, -0.006255f},
66 {0.266713f, 0.963776f, 0.023572f, -0.006836f},
67 {0.290285f, 0.956940f, 0.023397f, -0.007412f},
68 {0.313682f, 0.949528f, 0.023208f, -0.007984f},
69 {0.336890f, 0.941544f, 0.023005f, -0.008551f},
70 {0.359895f, 0.932993f, 0.022788f, -0.009113f},
71 {0.382683f, 0.923880f, 0.022558f, -0.009670f},
72 {0.405241f, 0.914210f, 0.022314f, -0.010220f},
73 {0.427555f, 0.903989f, 0.022056f, -0.010765f},
74 {0.449611f, 0.893224f, 0.021785f, -0.011303f},
75 {0.471397f, 0.881921f, 0.021501f, -0.011834f},
76 {0.492898f, 0.870087f, 0.021205f, -0.012358f},
77 {0.514103f, 0.857729f, 0.020895f, -0.012875f},
78 {0.534998f, 0.844854f, 0.020573f, -0.013384f},
79 {0.555570f, 0.831470f, 0.020238f, -0.013885f},
80 {0.575808f, 0.817585f, 0.019891f, -0.014377f},
81 {0.595699f, 0.803208f, 0.019532f, -0.014861f},
82 {0.615232f, 0.788346f, 0.019162f, -0.015336f},
83 {0.634393f, 0.773010f, 0.018780f, -0.015802f},
84 {0.653173f, 0.757209f, 0.018386f, -0.016258f},
85 {0.671559f, 0.740951f, 0.017982f, -0.016704f},
86 {0.689541f, 0.724247f, 0.017566f, -0.017140f},
87 {0.707107f, 0.707107f, 0.017140f, -0.017566f},
88 {0.724247f, 0.689541f, 0.016704f, -0.017982f},
89 {0.740951f, 0.671559f, 0.016258f, -0.018386f},
90 {0.757209f, 0.653173f, 0.015802f, -0.018780f},
91 {0.773010f, 0.634393f, 0.015336f, -0.019162f},
92 {0.788346f, 0.615232f, 0.014861f, -0.019532f},
93 {0.803208f, 0.595699f, 0.014377f, -0.019891f},
94 {0.817585f, 0.575808f, 0.013885f, -0.020238f},
95 {0.831470f, 0.555570f, 0.013384f, -0.020573f},
96 {0.844854f, 0.534998f, 0.012875f, -0.020895f},
97 {0.857729f, 0.514103f, 0.012358f, -0.021205f},
98 {0.870087f, 0.492898f, 0.011834f, -0.021501f},
99 {0.881921f, 0.471397f, 0.011303f, -0.021785f},
100 {0.893224f, 0.449611f, 0.010765f, -0.022056f},
101 {0.903989f, 0.427555f, 0.010220f, -0.022314f},
102 {0.914210f, 0.405241f, 0.009670f, -0.022558f},
103 {0.923880f, 0.382683f, 0.009113f, -0.022788f},
104 {0.932993f, 0.359895f, 0.008551f, -0.023005f},
105 {0.941544f, 0.336890f, 0.007984f, -0.023208f},
106 {0.949528f, 0.313682f, 0.007412f, -0.023397f},
107 {0.956940f, 0.290285f, 0.006836f, -0.023572f},
108 {0.963776f, 0.266713f, 0.006255f, -0.023733f},
109 {0.970031f, 0.242980f, 0.005671f, -0.023879f},
110 {0.975702f, 0.219101f, 0.005083f, -0.024011f},
111 {0.980785f, 0.195090f, 0.004492f, -0.024128f},
112 {0.985278f, 0.170962f, 0.003899f, -0.024231f},
113 {0.989177f, 0.146730f, 0.003303f, -0.024320f},
114 {0.992480f, 0.122411f, 0.002705f, -0.024394f},
115 {0.995185f, 0.098017f, 0.002106f, -0.024453f},
116 {0.997290f, 0.073565f, 0.001505f, -0.024497f},
117 {0.998795f, 0.049068f, 0.000903f, -0.024526f},
118 {0.999699f, 0.024541f, 0.000301f, -0.024541f},
119 {1.000000f, 0.000000f, -0.000301f, -0.024541f},
120 {0.999699f, -0.024541f, -0.000903f, -0.024526f},
121 {0.998795f, -0.049068f, -0.001505f, -0.024497f},
122 {0.997290f, -0.073565f, -0.002106f, -0.024453f},
123 {0.995185f, -0.098017f, -0.002705f, -0.024394f},
124 {0.992480f, -0.122411f, -0.003303f, -0.024320f},
125 {0.989177f, -0.146730f, -0.003899f, -0.024231f},
126 {0.985278f, -0.170962f, -0.004492f, -0.024128f},
127 {0.980785f, -0.195090f, -0.005083f, -0.024011f},
128 {0.975702f, -0.219101f, -0.005671f, -0.023879f},
129 {0.970031f, -0.242980f, -0.006255f, -0.023733f},
130 {0.963776f, -0.266713f, -0.006836f, -0.023572f},
131 {0.956940f, -0.290285f, -0.007412f, -0.023397f},
132 {0.949528f, -0.313682f, -0.007984f, -0.023208f},
133 {0.941544f, -0.336890f, -0.008551f, -0.023005f},
134 {0.932993f, -0.359895f, -0.009113f, -0.022788f},
135 {0.923880f, -0.382683f, -0.009670f, -0.022558f},
136 {0.914210f, -0.405241f, -0.010220f, -0.022314f},
137 {0.903989f, -0.427555f, -0.010765f, -0.022056f},
138 {0.893224f, -0.449611f, -0.011303f, -0.021785f},
139 {0.881921f, -0.471397f, -0.011834f, -0.021501f},
140 {0.870087f, -0.492898f, -0.012358f, -0.021205f},
141 {0.857729f, -0.514103f, -0.012875f, -0.020895f},
142 {0.844854f, -0.534998f, -0.013384f, -0.020573f},
143 {0.831470f, -0.555570f, -0.013885f, -0.020238f},
144 {0.817585f, -0.575808f, -0.014377f, -0.019891f},
145 {0.803208f, -0.595699f, -0.014861f, -0.019532f},
146 {0.788346f, -0.615232f, -0.015336f, -0.019162f},
147 {0.773010f, -0.634393f, -0.015802f, -0.018780f},
148 {0.757209f, -0.653173f, -0.016258f, -0.018386f},
149 {0.740951f, -0.671559f, -0.016704f, -0.017982f},
150 {0.724247f, -0.689541f, -0.017140f, -0.017566f},
151 {0.707107f, -0.707107f, -0.017566f, -0.017140f},
152 {0.689541f, -0.724247f, -0.017982f, -0.016704f},
153 {0.671559f, -0.740951f, -0.018386f, -0.016258f},
154 {0.653173f, -0.757209f, -0.018780f, -0.015802f},
155 {0.634393f, -0.773010f, -0.019162f, -0.015336f},
156 {0.615232f, -0.788346f, -0.019532f, -0.014861f},
157 {0.595699f, -0.803208f, -0.019891f, -0.014377f},
158 {0.575808f, -0.817585f, -0.020238f, -0.013885f},
159 {0.555570f, -0.831470f, -0.020573f, -0.013384f},
160 {0.534998f, -0.844854f, -0.020895f, -0.012875f},
161 {0.514103f, -0.857729f, -0.021205f, -0.012358f},
162 {0.492898f, -0.870087f, -0.021501f, -0.011834f},
163 {0.471397f, -0.881921f, -0.021785f, -0.011303f},
164 {0.449611f, -0.893224f, -0.022056f, -0.010765f},
165 {0.427555f, -0.903989f, -0.022314f, -0.010220f},
166 {0.405241f, -0.914210f, -0.022558f, -0.009670f},
167 {0.382683f, -0.923880f, -0.022788f, -0.009113f},
168 {0.359895f, -0.932993f, -0.023005f, -0.008551f},
169 {0.336890f, -0.941544f, -0.023208f, -0.007984f},
170 {0.313682f, -0.949528f, -0.023397f, -0.007412f},
171 {0.290285f, -0.956940f, -0.023572f, -0.006836f},
172 {0.266713f, -0.963776f, -0.023733f, -0.006255f},
173 {0.242980f, -0.970031f, -0.023879f, -0.005671f},
174 {0.219101f, -0.975702f, -0.024011f, -0.005083f},
175 {0.195090f, -0.980785f, -0.024128f, -0.004492f},
176 {0.170962f, -0.985278f, -0.024231f, -0.003899f},
177 {0.146730f, -0.989177f, -0.024320f, -0.003303f},
178 {0.122411f, -0.992480f, -0.024394f, -0.002705f},
179 {0.098017f, -0.995185f, -0.024453f, -0.002106f},
180 {0.073565f, -0.997290f, -0.024497f, -0.001505f},
181 {0.049068f, -0.998795f, -0.024526f, -0.000903f},
182 {0.024541f, -0.999699f, -0.024541f, -0.000301f},
183 {0.000000f, -1.000000f, -0.024541f, 0.000301f},
184 {-0.024541f, -0.999699f, -0.024526f, 0.000903f},
185 {-0.049068f, -0.998795f, -0.024497f, 0.001505f},
186 {-0.073565f, -0.997290f, -0.024453f, 0.002106f},
187 {-0.098017f, -0.995185f, -0.024394f, 0.002705f},
188 {-0.122411f, -0.992480f, -0.024320f, 0.003303f},
189 {-0.146730f, -0.989177f, -0.024231f, 0.003899f},
190 {-0.170962f, -0.985278f, -0.024128f, 0.004492f},
191 {-0.195090f, -0.980785f, -0.024011f, 0.005083f},
192 {-0.219101f, -0.975702f, -0.023879f, 0.005671f},
193 {-0.242980f, -0.970031f, -0.023733f, 0.006255f},
194 {-0.266713f, -0.963776f, -0.023572f, 0.006836f},
195 {-0.290285f, -0.956940f, -0.023397f, 0.007412f},
196 {-0.313682f, -0.949528f, -0.023208f, 0.007984f},
197 {-0.336890f, -0.941544f, -0.023005f, 0.008551f},
198 {-0.359895f, -0.932993f, -0.022788f, 0.009113f},
199 {-0.382683f, -0.923880f, -0.022558f, 0.009670f},
200 {-0.405241f, -0.914210f, -0.022314f, 0.010220f},
201 {-0.427555f, -0.903989f, -0.022056f, 0.010765f},
202 {-0.449611f, -0.893224f, -0.021785f, 0.011303f},
203 {-0.471397f, -0.881921f, -0.021501f, 0.011834f},
204 {-0.492898f, -0.870087f, -0.021205f, 0.012358f},
205 {-0.514103f, -0.857729f, -0.020895f, 0.012875f},
206 {-0.534998f, -0.844854f, -0.020573f, 0.013384f},
207 {-0.555570f, -0.831470f, -0.020238f, 0.013885f},
208 {-0.575808f, -0.817585f, -0.019891f, 0.014377f},
209 {-0.595699f, -0.803208f, -0.019532f, 0.014861f},
210 {-0.615232f, -0.788346f, -0.019162f, 0.015336f},
211 {-0.634393f, -0.773010f, -0.018780f, 0.015802f},
212 {-0.653173f, -0.757209f, -0.018386f, 0.016258f},
213 {-0.671559f, -0.740951f, -0.017982f, 0.016704f},
214 {-0.689541f, -0.724247f, -0.017566f, 0.017140f},
215 {-0.707107f, -0.707107f, -0.017140f, 0.017566f},
216 {-0.724247f, -0.689541f, -0.016704f, 0.017982f},
217 {-0.740951f, -0.671559f, -0.016258f, 0.018386f},
218 {-0.757209f, -0.653173f, -0.015802f, 0.018780f},
219 {-0.773010f, -0.634393f, -0.015336f, 0.019162f},
220 {-0.788346f, -0.615232f, -0.014861f, 0.019532f},
221 {-0.803208f, -0.595699f, -0.014377f, 0.019891f},
222 {-0.817585f, -0.575808f, -0.013885f, 0.020238f},
223 {-0.831470f, -0.555570f, -0.013384f, 0.020573f},
224 {-0.844854f, -0.534998f, -0.012875f, 0.020895f},
225 {-0.857729f, -0.514103f, -0.012358f, 0.021205f},
226 {-0.870087f, -0.492898f, -0.011834f, 0.021501f},
227 {-0.881921f, -0.471397f, -0.011303f, 0.021785f},
228 {-0.893224f, -0.449611f, -0.010765f, 0.022056f},
229 {-0.903989f, -0.427555f, -0.010220f, 0.022314f},
230 {-0.914210f, -0.405241f, -0.009670f, 0.022558f},
231 {-0.923880f, -0.382683f, -0.009113f, 0.022788f},
232 {-0.932993f, -0.359895f, -0.008551f, 0.023005f},
233 {-0.941544f, -0.336890f, -0.007984f, 0.023208f},
234 {-0.949528f, -0.313682f, -0.007412f, 0.023397f},
235 {-0.956940f, -0.290285f, -0.006836f, 0.023572f},
236 {-0.963776f, -0.266713f, -0.006255f, 0.023733f},
237 {-0.970031f, -0.242980f, -0.005671f, 0.023879f},
238 {-0.975702f, -0.219101f, -0.005083f, 0.024011f},
239 {-0.980785f, -0.195090f, -0.004492f, 0.024128f},
240 {-0.985278f, -0.170962f, -0.003899f, 0.024231f},
241 {-0.989177f, -0.146730f, -0.003303f, 0.024320f},
242 {-0.992480f, -0.122411f, -0.002705f, 0.024394f},
243 {-0.995185f, -0.098017f, -0.002106f, 0.024453f},
244 {-0.997290f, -0.073565f, -0.001505f, 0.024497f},
245 {-0.998795f, -0.049068f, -0.000903f, 0.024526f},
246 {-0.999699f, -0.024541f, -0.000301f, 0.024541f},
247 {-1.000000f, -0.000000f, 0.000301f, 0.024541f},
248 {-0.999699f, 0.024541f, 0.000903f, 0.024526f},
249 {-0.998795f, 0.049068f, 0.001505f, 0.024497f},
250 {-0.997290f, 0.073565f, 0.002106f, 0.024453f},
251 {-0.995185f, 0.098017f, 0.002705f, 0.024394f},
252 {-0.992480f, 0.122411f, 0.003303f, 0.024320f},
253 {-0.989177f, 0.146730f, 0.003899f, 0.024231f},
254 {-0.985278f, 0.170962f, 0.004492f, 0.024128f},
255 {-0.980785f, 0.195090f, 0.005083f, 0.024011f},
256 {-0.975702f, 0.219101f, 0.005671f, 0.023879f},
257 {-0.970031f, 0.242980f, 0.006255f, 0.023733f},
258 {-0.963776f, 0.266713f, 0.006836f, 0.023572f},
259 {-0.956940f, 0.290285f, 0.007412f, 0.023397f},
260 {-0.949528f, 0.313682f, 0.007984f, 0.023208f},
261 {-0.941544f, 0.336890f, 0.008551f, 0.023005f},
262 {-0.932993f, 0.359895f, 0.009113f, 0.022788f},
263 {-0.923880f, 0.382683f, 0.009670f, 0.022558f},
264 {-0.914210f, 0.405241f, 0.010220f, 0.022314f},
265 {-0.903989f, 0.427555f, 0.010765f, 0.022056f},
266 {-0.893224f, 0.449611f, 0.011303f, 0.021785f},
267 {-0.881921f, 0.471397f, 0.011834f, 0.021501f},
268 {-0.870087f, 0.492898f, 0.012358f, 0.021205f},
269 {-0.857729f, 0.514103f, 0.012875f, 0.020895f},
270 {-0.844854f, 0.534998f, 0.013384f, 0.020573f},
271 {-0.831470f, 0.555570f, 0.013885f, 0.020238f},
272 {-0.817585f, 0.575808f, 0.014377f, 0.019891f},
273 {-0.803208f, 0.595699f, 0.014861f, 0.019532f},
274 {-0.788346f, 0.615232f, 0.015336f, 0.019162f},
275 {-0.773010f, 0.634393f, 0.015802f, 0.018780f},
276 {-0.757209f, 0.653173f, 0.016258f, 0.018386f},
277 {-0.740951f, 0.671559f, 0.016704f, 0.017982f},
278 {-0.724247f, 0.689541f, 0.017140f, 0.017566f},
279 {-0.707107f, 0.707107f, 0.017566f, 0.017140f},
280 {-0.689541f, 0.724247f, 0.017982f, 0.016704f},
281 {-0.671559f, 0.740951f, 0.018386f, 0.016258f},
282 {-0.653173f, 0.757209f, 0.018780f, 0.015802f},
283 {-0.634393f, 0.773010f, 0.019162f, 0.015336f},
284 {-0.615232f, 0.788346f, 0.019532f, 0.014861f},
285 {-0.595699f, 0.803208f, 0.019891f, 0.014377f},
286 {-0.575808f, 0.817585f, 0.020238f, 0.013885f},
287 {-0.555570f, 0.831470f, 0.020573f, 0.013384f},
288 {-0.534998f, 0.844854f, 0.020895f, 0.012875f},
289 {-0.514103f, 0.857729f, 0.021205f, 0.012358f},
290 {-0.492898f, 0.870087f, 0.021501f, 0.011834f},
291 {-0.471397f, 0.881921f, 0.021785f, 0.011303f},
292 {-0.449611f, 0.893224f, 0.022056f, 0.010765f},
293 {-0.427555f, 0.903989f, 0.022314f, 0.010220f},
294 {-0.405241f, 0.914210f, 0.022558f, 0.009670f},
295 {-0.382683f, 0.923880f, 0.022788f, 0.009113f},
296 {-0.359895f, 0.932993f, 0.023005f, 0.008551f},
297 {-0.336890f, 0.941544f, 0.023208f, 0.007984f},
298 {-0.313682f, 0.949528f, 0.023397f, 0.007412f},
299 {-0.290285f, 0.956940f, 0.023572f, 0.006836f},
300 {-0.266713f, 0.963776f, 0.023733f, 0.006255f},
301 {-0.242980f, 0.970031f, 0.023879f, 0.005671f},
302 {-0.219101f, 0.975702f, 0.024011f, 0.005083f},
303 {-0.195090f, 0.980785f, 0.024128f, 0.004492f},
304 {-0.170962f, 0.985278f, 0.024231f, 0.003899f},
305 {-0.146730f, 0.989177f, 0.024320f, 0.003303f},
306 {-0.122411f, 0.992480f, 0.024394f, 0.002705f},
307 {-0.098017f, 0.995185f, 0.024453f, 0.002106f},
308 {-0.073565f, 0.997290f, 0.024497f, 0.001505f},
309 {-0.049068f, 0.998795f, 0.024526f, 0.000903f},
310 {-0.024541f, 0.999699f, 0.024541f, 0.000301f},
311 {-0.000000f, 1.000000f, 0.024541f, -0.000301f},
315static constexpr AtanEntry sArcTanTbl[32 + 1] = {
316 {0.000000000f, 1.272825321f},
317 {1.272825321f, 1.270345790f},
318 {2.543171111f, 1.265415586f},
319 {3.808586697f, 1.258091595f},
320 {5.066678293f, 1.248457103f},
321 {6.315135396f, 1.236619467f},
322 {7.551754863f, 1.222707202f},
323 {8.774462065f, 1.206866624f},
324 {9.981328688f, 1.189258212f},
325 {11.170586901f, 1.170052841f},
326 {12.340639741f, 1.149428034f},
327 {13.490067775f, 1.127564381f},
328 {14.617632156f, 1.104642222f},
329 {15.722274378f, 1.080838675f},
330 {16.803113053f, 1.056325088f},
331 {17.859438141f, 1.031264918f},
332 {18.890703059f, 1.005812061f},
333 {19.896515121f, 0.980109621f},
334 {20.876624742f, 0.954289072f},
335 {21.830913814f, 0.928469801f},
336 {22.759383615f, 0.902758952f},
337 {23.662142567f, 0.877251558f},
338 {24.539394125f, 0.852030871f},
339 {25.391424996f, 0.827168886f},
340 {26.218593881f, 0.802726967f},
341 {27.021320848f, 0.778756582f},
342 {27.800077430f, 0.755300081f},
343 {28.555377511f, 0.732391496f},
344 {29.287769007f, 0.710057351f},
345 {29.997826358f, 0.688317453f},
346 {30.686143811f, 0.667185647f},
347 {31.353329458f, 0.646670542f},
348 {32.000000000f, 0.626776175f},
352[[nodiscard]]
static inline constexpr f32 SinFIdx(f32 fidx) {
353 f32 abs_fidx = fabs(fidx);
355 while (abs_fidx >= 65536.0f) {
356 abs_fidx -= 65536.0f;
359 u16 idx =
static_cast<u16
>(abs_fidx);
360 f32 r = abs_fidx -
static_cast<f32
>(idx);
362 f32 val = sSinCosTbl[idx].sinVal + r * sSinCosTbl[idx].sinDt;
363 return fidx < 0.0f ? -val : val;
367[[nodiscard]]
static inline constexpr f32 CosFIdx(f32 fidx) {
368 f32 abs_fidx = fabs(fidx);
370 while (abs_fidx >= 65536.0f) {
371 abs_fidx -= 65536.0f;
374 u16 idx =
static_cast<u16
>(abs_fidx);
375 f32 r = abs_fidx -
static_cast<f32
>(idx);
378 return sSinCosTbl[idx].cosVal + r * sSinCosTbl[idx].cosDt;
382[[nodiscard]]
static inline constexpr std::pair<f32, f32> SinCosFIdx(f32 fidx) {
383 f32 abs_fidx = fabs(fidx);
385 while (abs_fidx >= 65536.0f) {
386 abs_fidx -= 65536.0f;
389 u16 idx =
static_cast<u16
>(abs_fidx);
390 f32 r = abs_fidx -
static_cast<f32
>(idx);
393 f32
cos =
fma(sSinCosTbl[idx].cosDt, r, sSinCosTbl[idx].cosVal);
394 f32
sin =
fma(sSinCosTbl[idx].sinDt, r, sSinCosTbl[idx].sinVal);
403[[nodiscard]]
static inline constexpr f32 AtanFIdx_(f32 x) {
405 u16 idx =
static_cast<u16
>(x);
406 f32 r = x -
static_cast<f32
>(idx);
407 return sArcTanTbl[idx].atanVal + r * sArcTanTbl[idx].atanDt;
411[[nodiscard]]
static inline constexpr f32 Atan2FIdx(f32 y, f32 x) {
412 if (x == 0.0f && y == 0.0f) {
419 return 0.0f + AtanFIdx_(y / x);
421 return 64.0f - AtanFIdx_(x / y);
425 return 0.0f - AtanFIdx_(-y / x);
427 return -64.0f + AtanFIdx_(x / -y);
433 return 128.0f - AtanFIdx_(y / -x);
435 return 64.0f + AtanFIdx_(-x / y);
439 return -128.0f + AtanFIdx_(-y / -x);
441 return -64.0f - AtanFIdx_(-x / -y);
449[[nodiscard]]
static inline constexpr f32
sin(f32 x) {
450 return SinFIdx(x * RAD2FIDX);
455[[nodiscard]]
static inline constexpr f32
cos(f32 x) {
456 return CosFIdx(x * RAD2FIDX);
460[[nodiscard]]
static inline constexpr f32 asin(f32 x) {
461 return static_cast<f32
>(::asin(
static_cast<f64
>(x)));
465[[nodiscard]]
static inline constexpr f32 acos(f32 x) {
466 return static_cast<f32
>(::acos(
static_cast<f64
>(x)));
470[[nodiscard]]
static inline constexpr f32 atan2(f32 y, f32 x) {
471 return Atan2FIdx(y, x) * FIDX2RAD;
474[[nodiscard]]
static inline constexpr f32 abs(f32 x) {
491 constexpr c32(
const f32 p) {
495 constexpr c32(
const u32 p) {
504 constexpr c64(
const f64 p) {
508 constexpr c64(
const u64 p) {
516static constexpr u64 EXPONENT_SHIFT_F64 = 52;
517static constexpr u64 MANTISSA_MASK_F64 = 0x000fffffffffffffULL;
518static constexpr u64 EXPONENT_MASK_F64 = 0x7ff0000000000000ULL;
519static constexpr u64 SIGN_MASK_F64 = 0x8000000000000000ULL;
521static constexpr std::array<BaseAndDec64, 32> RSQRTE_TABLE = {{
522 {0x69fa000000000ULL, -0x15a0000000LL},
523 {0x5f2e000000000ULL, -0x13cc000000LL},
524 {0x554a000000000ULL, -0x1234000000LL},
525 {0x4c30000000000ULL, -0x10d4000000LL},
526 {0x43c8000000000ULL, -0x0f9c000000LL},
527 {0x3bfc000000000ULL, -0x0e88000000LL},
528 {0x34b8000000000ULL, -0x0d94000000LL},
529 {0x2df0000000000ULL, -0x0cb8000000LL},
530 {0x2794000000000ULL, -0x0bf0000000LL},
531 {0x219c000000000ULL, -0x0b40000000LL},
532 {0x1bfc000000000ULL, -0x0aa0000000LL},
533 {0x16ae000000000ULL, -0x0a0c000000LL},
534 {0x11a8000000000ULL, -0x0984000000LL},
535 {0x0ce6000000000ULL, -0x090c000000LL},
536 {0x0862000000000ULL, -0x0898000000LL},
537 {0x0416000000000ULL, -0x082c000000LL},
538 {0xffe8000000000ULL, -0x1e90000000LL},
539 {0xf0a4000000000ULL, -0x1c00000000LL},
540 {0xe2a8000000000ULL, -0x19c0000000LL},
541 {0xd5c8000000000ULL, -0x17c8000000LL},
542 {0xc9e4000000000ULL, -0x1610000000LL},
543 {0xbedc000000000ULL, -0x1490000000LL},
544 {0xb498000000000ULL, -0x1330000000LL},
545 {0xab00000000000ULL, -0x11f8000000LL},
546 {0xa204000000000ULL, -0x10e8000000LL},
547 {0x9994000000000ULL, -0x0fe8000000LL},
548 {0x91a0000000000ULL, -0x0f08000000LL},
549 {0x8a1c000000000ULL, -0x0e38000000LL},
550 {0x8304000000000ULL, -0x0d78000000LL},
551 {0x7c48000000000ULL, -0x0cc8000000LL},
552 {0x75e4000000000ULL, -0x0c28000000LL},
553 {0x6fd0000000000ULL, -0x0b98000000LL},
556[[nodiscard]]
static inline constexpr f64 frsqrte(
const f64 val) {
559 u64 mantissa = bits.u & MANTISSA_MASK_F64;
560 s64 exponent = bits.u & EXPONENT_MASK_F64;
561 bool sign = (bits.u & SIGN_MASK_F64) != 0;
564 if (mantissa == 0 && exponent == 0) {
565 return std::copysign(std::numeric_limits<f64>::infinity(), bits.f);
569 if (exponent == EXPONENT_MASK_F64) {
571 return sign ? std::numeric_limits<f64>::quiet_NaN() : 0.0;
579 return std::numeric_limits<f64>::quiet_NaN();
586 u32 shift = std::countl_zero(mantissa) -
static_cast<u32
>(63 - EXPONENT_SHIFT_F64);
589 mantissa &= MANTISSA_MASK_F64;
592 exponent -=
static_cast<s64
>(shift - 1) << EXPONENT_SHIFT_F64;
598 u32 key =
static_cast<u32
>((
static_cast<u64
>(exponent) | mantissa) >> 37);
600 (
static_cast<u64
>((0xbfcLL << EXPONENT_SHIFT_F64) - exponent) >> 1) & EXPONENT_MASK_F64;
603 const auto &entry = RSQRTE_TABLE[0x1f & (key >> 11)];
607 u64 new_mantissa =
static_cast<u64
>(entry.base + entry.dec *
static_cast<s64
>(key & 0x7ff));
609 return c64(new_exp | new_mantissa).f;
612static constexpr std::array<BaseAndDec32, 32> FRES_TABLE = {{
613 {0x00fff000UL, -0x3e1L},
614 {0x00f07000UL, -0x3a7L},
615 {0x00e1d400UL, -0x371L},
616 {0x00d41000UL, -0x340L},
617 {0x00c71000UL, -0x313L},
618 {0x00bac400UL, -0x2eaL},
619 {0x00af2000UL, -0x2c4L},
620 {0x00a41000UL, -0x2a0L},
621 {0x00999000UL, -0x27fL},
622 {0x008f9400UL, -0x261L},
623 {0x00861000UL, -0x245L},
624 {0x007d0000UL, -0x22aL},
625 {0x00745800UL, -0x212L},
626 {0x006c1000UL, -0x1fbL},
627 {0x00642800UL, -0x1e5L},
628 {0x005c9400UL, -0x1d1L},
629 {0x00555000UL, -0x1beL},
630 {0x004e5800UL, -0x1acL},
631 {0x0047ac00UL, -0x19bL},
632 {0x00413c00UL, -0x18bL},
633 {0x003b1000UL, -0x17cL},
634 {0x00352000UL, -0x16eL},
635 {0x002f5c00UL, -0x15bL},
636 {0x0029f000UL, -0x15bL},
637 {0x00248800UL, -0x143L},
638 {0x001f7c00UL, -0x143L},
639 {0x001a7000UL, -0x12dL},
640 {0x0015bc00UL, -0x12dL},
641 {0x00110800UL, -0x11aL},
642 {0x000ca000UL, -0x11aL},
643 {0x00083800UL, -0x108L},
644 {0x00041800UL, -0x106L},
647[[nodiscard]]
static inline constexpr f32 fres(
const f32 val) {
648 static constexpr u32 EXPONENT_SHIFT_F32 = 23;
649 static constexpr u64 EXPONENT_SHIFT_F64 = 52;
650 static constexpr u32 EXPONENT_MASK_F32 = 0x7f800000UL;
651 static constexpr u64 EXPONENT_MASK_F64 = 0x7ff0000000000000ULL;
652 static constexpr u32 MANTISSA_MASK_F32 = 0x007fffffUL;
653 static constexpr u32 SIGN_MASK_F32 = 0x80000000UL;
654 static constexpr u64 SIGN_MASK_F64 = 0x8000000000000000ULL;
655 static constexpr u64 QUIET_BIT_F64 = 0x0008000000000000ULL;
656 static constexpr c64 LARGEST_FLOAT(
static_cast<u64
>(0x47d0000000000000ULL));
660 u32 mantissa =
static_cast<u32
>(
661 bits.u >> (EXPONENT_SHIFT_F64 -
static_cast<u64
>(EXPONENT_SHIFT_F32))) &
663 s32 exponent =
static_cast<s32
>((bits.u & EXPONENT_MASK_F64) >> EXPONENT_SHIFT_F64) - 0x380;
664 u32 sign =
static_cast<u32
>(bits.u >> 32) & SIGN_MASK_F32;
667 bool nonzero = (bits.u & ~SIGN_MASK_F64) != 0;
671 c32 cresult(sign | (EXPONENT_MASK_F32 - (1 << EXPONENT_SHIFT_F32)) | MANTISSA_MASK_F32);
674 return std::copysignf(std::numeric_limits<f32>::infinity(), val);
678 if ((bits.u & EXPONENT_MASK_F64) >= LARGEST_FLOAT.u) {
679 if (mantissa == 0 || (bits.u & EXPONENT_MASK_F64) != EXPONENT_MASK_F64) {
681 return std::copysignf(0.0f, val);
682 }
else if ((bits.u & QUIET_BIT_F64) != 0) {
687 return std::numeric_limits<f32>::quiet_NaN();
692 u32 key = mantissa >> 18;
693 s32 new_exp = 253 - exponent;
694 const auto &entry = FRES_TABLE[key];
698 static_cast<u32
>(entry.base + entry.dec * (
static_cast<s32
>((mantissa >> 8) & 0x3ff)));
699 u32 new_mantissa = pre_shift >> 1;
706 u32 temp = sign |
static_cast<u32
>(new_exp) << EXPONENT_SHIFT_F32 | new_mantissa;
714[[nodiscard]]
static inline constexpr f32
frsqrt(f32 x) {
716 f64 est = frsqrte(x);
719 f32 tmp0 =
static_cast<f32
>(est *
force25Bit(est));
720 f32 tmp1 =
static_cast<f32
>(est *
static_cast<f64
>(0.5f));
722 static_cast<f32
>(
static_cast<f64
>(3.0f) -
static_cast<f64
>(tmp0) *
static_cast<f64
>(x));
727[[nodiscard]]
static inline constexpr f32 sqrt(f32 x) {
728 return x > 0.0f ? x *
frsqrt(x) : 0.0f;
732static inline constexpr u32 FindRootsQuadratic(f32 a, f32 b, f32 c, f32 &root1, f32 &root2) {
733 constexpr f32 EPSILON = 0.0002f;
752 f32 halfBOverA = b / (2.0f * a);
753 f32 normalizedC = c / (halfBOverA * (a * halfBOverA));
754 f32 normalizedDiscriminant = 1.0f - normalizedC;
756 if (normalizedDiscriminant > EPSILON) {
757 f32 sqrtNormalizedDiscriminant = normalizedDiscriminant *
frsqrt(normalizedDiscriminant);
758 root2 = (halfBOverA * normalizedC) / (-1.0f - sqrtNormalizedDiscriminant);
759 root1 = halfBOverA * (-1.0f - sqrtNormalizedDiscriminant);
764 if (normalizedDiscriminant >= -EPSILON) {
773[[nodiscard]]
static inline constexpr f32
finv(f32 x) {
775 f32 invDouble = inv + inv;
776 f32 invSquare = inv * inv;
777 return -
fms(x, invSquare, invDouble);
795[[nodiscard]]
static inline constexpr f32
Hermite(f32 p0, f32 m0, f32 p1, f32 m1, f32 t) {
797 f32 t2_less_t = t2 - t;
798 f32 h3 = t2_less_t * t;
800 f32 h2 = h3 - t2_less_t;
803 return h3 * m1 + (h2 * m0 + (p0 - h1 * p0 + h1 * p1));