1use crate::dyadic_float::{DyadicFloat128, DyadicSign};
30use crate::round::RoundFinite;
31use crate::sincos_reduce_tables::ONE_TWENTY_EIGHT_OVER_PI;
32
33pub(crate) fn range_reduction_small_f128(x: f64) -> DyadicFloat128 {
34 const PI_OVER_128_F128: DyadicFloat128 = DyadicFloat128 {
35 sign: DyadicSign::Pos,
36 exponent: -133,
37 mantissa: 0xc90f_daa2_2168_c234_c4c6_628b_80dc_1cd1_u128,
38 };
39 const ONE_TWENTY_EIGHT_OVER_PI_D: f64 = f64::from_bits(0x40445f306dc9c883);
40 let prod_hi = x * ONE_TWENTY_EIGHT_OVER_PI_D;
41 let kd = prod_hi.round_finite();
42
43 let mk_f128 = DyadicFloat128::new_from_f64(-kd);
44 let x_f128 = DyadicFloat128::new_from_f64(x);
45 let over_pi3 = ONE_TWENTY_EIGHT_OVER_PI[3];
46 let p_hi = x_f128.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.0)));
47 let p_mid = x_f128.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.1)));
48 let p_lo = x_f128.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.2)));
49 let s_hi = p_hi.quick_add(&mk_f128);
50 let s_lo = p_mid.quick_add(&p_lo);
51 let y = s_hi.quick_add(&s_lo);
52 y.quick_mul(&PI_OVER_128_F128)
53}
54
55pub(crate) fn range_reduction_small_f128_f128(x: DyadicFloat128) -> (DyadicFloat128, i64) {
56 const PI_OVER_128_F128: DyadicFloat128 = DyadicFloat128 {
57 sign: DyadicSign::Pos,
58 exponent: -133,
59 mantissa: 0xc90f_daa2_2168_c234_c4c6_628b_80dc_1cd1_u128,
60 };
61 const ONE_TWENTY_EIGHT_OVER_PI_D: f64 = f64::from_bits(0x40445f306dc9c883);
62 let prod_hi = x.fast_as_f64() * ONE_TWENTY_EIGHT_OVER_PI_D;
63 let kd = prod_hi.round_finite();
64
65 let mk_f128 = DyadicFloat128::new_from_f64(-kd);
66 let over_pi3 = ONE_TWENTY_EIGHT_OVER_PI[3];
67 let p_hi = x.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.0)));
68 let p_mid = x.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.1)));
69 let p_lo = x.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.2)));
70 let p_lo_lo = x.quick_mul(&DyadicFloat128::new_from_f64(f64::from_bits(over_pi3.3)));
71 let s_hi = p_hi.quick_add(&mk_f128);
72 let s_lo = p_mid.quick_add(&p_lo);
73 let y = (s_hi + s_lo) + p_lo_lo;
74 (y.quick_mul(&PI_OVER_128_F128), kd as i64)
75}
76
77pub(crate) struct SinCosDyadic {
101 pub(crate) v_sin: DyadicFloat128,
102 pub(crate) v_cos: DyadicFloat128,
103}
104
105#[cold]
106pub(crate) fn sincos_eval_dyadic(u: &DyadicFloat128) -> SinCosDyadic {
107 let u_sq = u.quick_mul(u);
108
109 static SIN_COEFFS: [DyadicFloat128; 7] = [
111 DyadicFloat128 {
112 sign: DyadicSign::Pos,
113 exponent: -127,
114 mantissa: 0x80000000_00000000_00000000_00000000_u128,
115 }, DyadicFloat128 {
117 sign: DyadicSign::Neg,
118 exponent: -130,
119 mantissa: 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaab_u128,
120 }, DyadicFloat128 {
122 sign: DyadicSign::Pos,
123 exponent: -134,
124 mantissa: 0x88888888_88888888_88888888_88888889_u128,
125 }, DyadicFloat128 {
127 sign: DyadicSign::Neg,
128 exponent: -140,
129 mantissa: 0xd00d00d0_0d00d00d_00d00d00_d00d00d0_u128,
130 }, DyadicFloat128 {
132 sign: DyadicSign::Pos,
133 exponent: -146,
134 mantissa: 0xb8ef1d2a_b6399c7d_560e4472_800b8ef2_u128,
135 }, DyadicFloat128 {
137 sign: DyadicSign::Neg,
138 exponent: -153,
139 mantissa: 0xd7322b3f_aa271c7f_3a3f25c1_bee38f10_u128,
140 }, DyadicFloat128 {
142 sign: DyadicSign::Pos,
143 exponent: -160,
144 mantissa: 0xb092309d_43684be5_1c198e91_d7b4269e_u128,
145 }, ];
147
148 static COS_COEFFS: [DyadicFloat128; 7] = [
150 DyadicFloat128 {
151 sign: DyadicSign::Pos,
152 exponent: -127,
153 mantissa: 0x80000000_00000000_00000000_00000000_u128,
154 }, DyadicFloat128 {
156 sign: DyadicSign::Neg,
157 exponent: -128,
158 mantissa: 0x80000000_00000000_00000000_00000000_u128,
159 }, DyadicFloat128 {
161 sign: DyadicSign::Pos,
162 exponent: -132,
163 mantissa: 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaab_u128,
164 }, DyadicFloat128 {
166 sign: DyadicSign::Neg,
167 exponent: -137,
168 mantissa: 0xb60b60b6_0b60b60b_60b60b60_b60b60b6_u128,
169 }, DyadicFloat128 {
171 sign: DyadicSign::Pos,
172 exponent: -143,
173 mantissa: 0xd00d00d0_0d00d00d_00d00d00_d00d00d0_u128,
174 }, DyadicFloat128 {
176 sign: DyadicSign::Neg,
177 exponent: -149,
178 mantissa: 0x93f27dbb_c4fae397_780b69f5_333c725b_u128,
179 }, DyadicFloat128 {
181 sign: DyadicSign::Pos,
182 exponent: -156,
183 mantissa: 0x8f76c77f_c6c4bdaa_26d4c3d6_7f425f60_u128,
184 }, ];
186
187 let mut sin_u = SIN_COEFFS[6];
188 for i in (0..7).rev() {
189 sin_u = sin_u * u_sq + SIN_COEFFS[i];
190 }
191 sin_u = sin_u * *u;
192
193 let mut cos_u = COS_COEFFS[6];
194 for i in (0..7).rev() {
195 cos_u = cos_u * u_sq + COS_COEFFS[i];
196 }
197
198 SinCosDyadic {
199 v_sin: sin_u,
200 v_cos: cos_u,
201 }
202}
203
204pub(crate) static SIN_K_PI_OVER_128_F128: [DyadicFloat128; 65] = [
233 DyadicFloat128 {
234 sign: DyadicSign::Pos,
235 exponent: 0,
236 mantissa: 0x0_u128,
237 },
238 DyadicFloat128 {
239 sign: DyadicSign::Pos,
240 exponent: -133,
241 mantissa: 0xc90a_afbd_1b33_efc9_c539_edcb_fda0_cf2c_u128,
242 },
243 DyadicFloat128 {
244 sign: DyadicSign::Pos,
245 exponent: -132,
246 mantissa: 0xc8fb_2f88_6ec0_9f37_6a17_954b_2b7c_5171_u128,
247 },
248 DyadicFloat128 {
249 sign: DyadicSign::Pos,
250 exponent: -131,
251 mantissa: 0x96a9_0496_70cf_ae65_f775_7409_4d3c_35c4_u128,
252 },
253 DyadicFloat128 {
254 sign: DyadicSign::Pos,
255 exponent: -131,
256 mantissa: 0xc8bd_35e1_4da1_5f0e_c739_6c89_4bbf_7389_u128,
257 },
258 DyadicFloat128 {
259 sign: DyadicSign::Pos,
260 exponent: -131,
261 mantissa: 0xfab2_72b5_4b98_71a2_7047_29ae_56d7_8a37_u128,
262 },
263 DyadicFloat128 {
264 sign: DyadicSign::Pos,
265 exponent: -130,
266 mantissa: 0x9640_8374_7309_d113_000a_89a1_1e07_c1ff_u128,
267 },
268 DyadicFloat128 {
269 sign: DyadicSign::Pos,
270 exponent: -130,
271 mantissa: 0xaf10_a224_59fe_32a6_3fee_f3bb_58b1_f10d_u128,
272 },
273 DyadicFloat128 {
274 sign: DyadicSign::Pos,
275 exponent: -130,
276 mantissa: 0xc7c5_c1e3_4d30_55b2_5cc8_c00e_4fcc_d850_u128,
277 },
278 DyadicFloat128 {
279 sign: DyadicSign::Pos,
280 exponent: -130,
281 mantissa: 0xe05c_1353_f27b_17e5_0ebc_61ad_e6ca_83cc_u128,
282 },
283 DyadicFloat128 {
284 sign: DyadicSign::Pos,
285 exponent: -130,
286 mantissa: 0xf8cf_cbd9_0af8_d57a_4221_dc4b_a772_598d_u128,
287 },
288 DyadicFloat128 {
289 sign: DyadicSign::Pos,
290 exponent: -129,
291 mantissa: 0x888e_9315_8fb3_bb04_9841_56f5_5334_4306_u128,
292 },
293 DyadicFloat128 {
294 sign: DyadicSign::Pos,
295 exponent: -129,
296 mantissa: 0x94a0_3176_acf8_2d45_ae4b_a773_da6b_f754_u128,
297 },
298 DyadicFloat128 {
299 sign: DyadicSign::Pos,
300 exponent: -129,
301 mantissa: 0xa09a_e4a0_bb30_0a19_2f89_5f44_a303_cc0b_u128,
302 },
303 DyadicFloat128 {
304 sign: DyadicSign::Pos,
305 exponent: -129,
306 mantissa: 0xac7c_d3ad_58fe_e7f0_811f_9539_84ef_f83e_u128,
307 },
308 DyadicFloat128 {
309 sign: DyadicSign::Pos,
310 exponent: -129,
311 mantissa: 0xb844_2987_d22c_f576_9cc3_ef36_746d_e3b8_u128,
312 },
313 DyadicFloat128 {
314 sign: DyadicSign::Pos,
315 exponent: -129,
316 mantissa: 0xc3ef_1535_754b_168d_3122_c2a5_9efd_dc37_u128,
317 },
318 DyadicFloat128 {
319 sign: DyadicSign::Pos,
320 exponent: -129,
321 mantissa: 0xcf7b_ca1d_476c_516d_a812_90bd_baad_62e4_u128,
322 },
323 DyadicFloat128 {
324 sign: DyadicSign::Pos,
325 exponent: -129,
326 mantissa: 0xdae8_804f_0ae6_015b_362c_b974_182e_3030_u128,
327 },
328 DyadicFloat128 {
329 sign: DyadicSign::Pos,
330 exponent: -129,
331 mantissa: 0xe633_74c9_8e22_f0b4_2872_ce1b_fc7a_d1cc_u128,
332 },
333 DyadicFloat128 {
334 sign: DyadicSign::Pos,
335 exponent: -129,
336 mantissa: 0xf15a_e9c0_37b1_d8f0_6c48_e9e3_420b_0f1d_u128,
337 },
338 DyadicFloat128 {
339 sign: DyadicSign::Pos,
340 exponent: -129,
341 mantissa: 0xfc5d_26df_c4d5_cfda_27c0_7c91_1290_b8d1_u128,
342 },
343 DyadicFloat128 {
344 sign: DyadicSign::Pos,
345 exponent: -128,
346 mantissa: 0x839c_3cc9_17ff_6cb4_bfd7_9717_f288_0abf_u128,
347 },
348 DyadicFloat128 {
349 sign: DyadicSign::Pos,
350 exponent: -128,
351 mantissa: 0x88f5_9aa0_da59_1421_b892_ca83_61d8_c84c_u128,
352 },
353 DyadicFloat128 {
354 sign: DyadicSign::Pos,
355 exponent: -128,
356 mantissa: 0x8e39_d9cd_7346_4364_bba4_cfec_bff5_4868_u128,
357 },
358 DyadicFloat128 {
359 sign: DyadicSign::Pos,
360 exponent: -128,
361 mantissa: 0x9368_2a66_e896_f544_b178_2191_1e71_c16e_u128,
362 },
363 DyadicFloat128 {
364 sign: DyadicSign::Pos,
365 exponent: -128,
366 mantissa: 0x987f_bfe7_0b81_a708_19ce_c845_ac87_a5c6_u128,
367 },
368 DyadicFloat128 {
369 sign: DyadicSign::Pos,
370 exponent: -128,
371 mantissa: 0x9d7f_d149_0285_c9e3_e25e_3954_9638_ae67_u128,
372 },
373 DyadicFloat128 {
374 sign: DyadicSign::Pos,
375 exponent: -128,
376 mantissa: 0xa267_9928_48ee_b0c0_3b51_67ee_359a_234e_u128,
377 },
378 DyadicFloat128 {
379 sign: DyadicSign::Pos,
380 exponent: -128,
381 mantissa: 0xa736_55df_1f2f_489e_149f_6e75_9934_68a2_u128,
382 },
383 DyadicFloat128 {
384 sign: DyadicSign::Pos,
385 exponent: -128,
386 mantissa: 0xabeb_49a4_6764_fd15_1bec_da80_89c1_a94c_u128,
387 },
388 DyadicFloat128 {
389 sign: DyadicSign::Pos,
390 exponent: -128,
391 mantissa: 0xb085_baa8_e966_f6da_e4ca_d00d_5c94_bcd1_u128,
392 },
393 DyadicFloat128 {
394 sign: DyadicSign::Pos,
395 exponent: -128,
396 mantissa: 0xb504_f333_f9de_6484_597d_89b3_754a_be9f_u128,
397 },
398 DyadicFloat128 {
399 sign: DyadicSign::Pos,
400 exponent: -128,
401 mantissa: 0xb968_41bf_7ffc_b21a_9de1_e3b2_2b8b_f4db_u128,
402 },
403 DyadicFloat128 {
404 sign: DyadicSign::Pos,
405 exponent: -128,
406 mantissa: 0xbdae_f913_557d_76f0_ac85_320f_528d_6d5c_u128,
407 },
408 DyadicFloat128 {
409 sign: DyadicSign::Pos,
410 exponent: -128,
411 mantissa: 0xc1d8_705f_fcbb_6e90_bdf0_715c_b8b2_0bd7_u128,
412 },
413 DyadicFloat128 {
414 sign: DyadicSign::Pos,
415 exponent: -128,
416 mantissa: 0xc5e4_0358_a8ba_05a7_43da_25d9_9267_326b_u128,
417 },
418 DyadicFloat128 {
419 sign: DyadicSign::Pos,
420 exponent: -128,
421 mantissa: 0xc9d1_124c_931f_da7a_8335_241b_e169_3225_u128,
422 },
423 DyadicFloat128 {
424 sign: DyadicSign::Pos,
425 exponent: -128,
426 mantissa: 0xcd9f_023f_9c3a_059e_23af_31db_7179_a4a9_u128,
427 },
428 DyadicFloat128 {
429 sign: DyadicSign::Pos,
430 exponent: -128,
431 mantissa: 0xd14d_3d02_313c_0eed_744f_ea20_e8ab_ef92_u128,
432 },
433 DyadicFloat128 {
434 sign: DyadicSign::Pos,
435 exponent: -128,
436 mantissa: 0xd4db_3148_750d_1819_f630_e8b6_dac8_3e68_u128,
437 },
438 DyadicFloat128 {
439 sign: DyadicSign::Pos,
440 exponent: -128,
441 mantissa: 0xd848_52c0_a80f_fcdb_24b9_fe00_6635_74a4_u128,
442 },
443 DyadicFloat128 {
444 sign: DyadicSign::Pos,
445 exponent: -128,
446 mantissa: 0xdb94_1a28_cb71_ec87_2c19_b632_53da_43fb_u128,
447 },
448 DyadicFloat128 {
449 sign: DyadicSign::Pos,
450 exponent: -128,
451 mantissa: 0xdebe_0563_7ca9_4cfb_4b19_aa71_fec3_ae6c_u128,
452 },
453 DyadicFloat128 {
454 sign: DyadicSign::Pos,
455 exponent: -128,
456 mantissa: 0xe1c5_978c_05ed_8691_f4e8_a837_2f8c_5810_u128,
457 },
458 DyadicFloat128 {
459 sign: DyadicSign::Pos,
460 exponent: -128,
461 mantissa: 0xe4aa_5909_a08f_a7b4_1227_85ae_67f5_515c_u128,
462 },
463 DyadicFloat128 {
464 sign: DyadicSign::Pos,
465 exponent: -128,
466 mantissa: 0xe76b_d7a1_e63b_9786_1251_2952_9d48_a92f_u128,
467 },
468 DyadicFloat128 {
469 sign: DyadicSign::Pos,
470 exponent: -128,
471 mantissa: 0xea09_a68a_6e49_cd62_15ad_45b4_a1b5_e823_u128,
472 },
473 DyadicFloat128 {
474 sign: DyadicSign::Pos,
475 exponent: -128,
476 mantissa: 0xec83_5e79_946a_3145_7e61_0231_ac1d_6181_u128,
477 },
478 DyadicFloat128 {
479 sign: DyadicSign::Pos,
480 exponent: -128,
481 mantissa: 0xeed8_9db6_6611_e307_86f8_c20f_b664_b01b_u128,
482 },
483 DyadicFloat128 {
484 sign: DyadicSign::Pos,
485 exponent: -128,
486 mantissa: 0xf109_0827_b437_25fd_6712_7db3_5b28_7315_u128,
487 },
488 DyadicFloat128 {
489 sign: DyadicSign::Pos,
490 exponent: -128,
491 mantissa: 0xf314_4762_4708_8f74_a548_6bdc_455d_56a3_u128,
492 },
493 DyadicFloat128 {
494 sign: DyadicSign::Pos,
495 exponent: -128,
496 mantissa: 0xf4fa_0ab6_316e_d2ec_163c_5c7f_03b7_18c5_u128,
497 },
498 DyadicFloat128 {
499 sign: DyadicSign::Pos,
500 exponent: -128,
501 mantissa: 0xf6ba_073b_424b_19e8_2c79_1f59_cc1f_fc23_u128,
502 },
503 DyadicFloat128 {
504 sign: DyadicSign::Pos,
505 exponent: -128,
506 mantissa: 0xf853_f7dc_9186_b952_c7ad_c6b4_9888_91ba_u128,
507 },
508 DyadicFloat128 {
509 sign: DyadicSign::Pos,
510 exponent: -128,
511 mantissa: 0xf9c7_9d63_272c_4628_4504_ae08_d19b_2981_u128,
512 },
513 DyadicFloat128 {
514 sign: DyadicSign::Pos,
515 exponent: -128,
516 mantissa: 0xfb14_be7f_bae5_8156_2172_a361_fd2a_722f_u128,
517 },
518 DyadicFloat128 {
519 sign: DyadicSign::Pos,
520 exponent: -128,
521 mantissa: 0xfc3b_27d3_8a5d_49ab_2567_78ff_cb5c_1769_u128,
522 },
523 DyadicFloat128 {
524 sign: DyadicSign::Pos,
525 exponent: -128,
526 mantissa: 0xfd3a_abf8_4528_b50b_eae6_bd95_1c1d_abbd_u128,
527 },
528 DyadicFloat128 {
529 sign: DyadicSign::Pos,
530 exponent: -128,
531 mantissa: 0xfe13_2387_0cfe_9a3d_90cd_1d95_9db6_74ef_u128,
532 },
533 DyadicFloat128 {
534 sign: DyadicSign::Pos,
535 exponent: -128,
536 mantissa: 0xfec4_6d1e_8929_2cf0_4139_0efd_c726_e9ef_u128,
537 },
538 DyadicFloat128 {
539 sign: DyadicSign::Pos,
540 exponent: -128,
541 mantissa: 0xff4e_6d68_0c41_d0a9_0f66_8633_f1ab_858a_u128,
542 },
543 DyadicFloat128 {
544 sign: DyadicSign::Pos,
545 exponent: -128,
546 mantissa: 0xffb1_0f1b_cb6b_ef1d_421e_8eda_af59_453e_u128,
547 },
548 DyadicFloat128 {
549 sign: DyadicSign::Pos,
550 exponent: -128,
551 mantissa: 0xffec_4304_2668_65d9_5657_5523_6696_1732_u128,
552 },
553 DyadicFloat128 {
554 sign: DyadicSign::Pos,
555 exponent: -127,
556 mantissa: 0x8000_0000_0000_0000_0000_0000_0000_0000_u128,
557 },
558];