1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.util;
23
24 import org.hipparchus.CalculusFieldElement;
25 import org.hipparchus.exception.LocalizedCoreFormats;
26 import org.hipparchus.exception.MathRuntimeException;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 public class FastMath {
81
82 public static final double PI = 105414357.0 / 33554432.0 + 1.984187159361080883e-9;
83
84
85 public static final double E = 2850325.0 / 1048576.0 + 8.254840070411028747e-8;
86
87
88 static final int EXP_INT_TABLE_MAX_INDEX = 750;
89
90 static final int EXP_INT_TABLE_LEN = EXP_INT_TABLE_MAX_INDEX * 2;
91
92 static final int LN_MANT_LEN = 1024;
93
94 static final int EXP_FRAC_TABLE_LEN = 1025;
95
96
97 private static final double LOG_MAX_VALUE = StrictMath.log(Double.MAX_VALUE);
98
99
100
101
102
103
104
105
106 private static final boolean RECOMPUTE_TABLES_AT_RUNTIME = false;
107
108
109 private static final double LN_2_A = 0.693147063255310059;
110
111
112 private static final double LN_2_B = 1.17304635250823482e-7;
113
114
115 private static final double[][] LN_QUICK_COEF = {
116 {1.0, 5.669184079525E-24},
117 {-0.25, -0.25},
118 {0.3333333134651184, 1.986821492305628E-8},
119 {-0.25, -6.663542893624021E-14},
120 {0.19999998807907104, 1.1921056801463227E-8},
121 {-0.1666666567325592, -7.800414592973399E-9},
122 {0.1428571343421936, 5.650007086920087E-9},
123 {-0.12502530217170715, -7.44321345601866E-11},
124 {0.11113807559013367, 9.219544613762692E-9},
125 };
126
127
128 private static final double[][] LN_HI_PREC_COEF = {
129 {1.0, -6.032174644509064E-23},
130 {-0.25, -0.25},
131 {0.3333333134651184, 1.9868161777724352E-8},
132 {-0.2499999701976776, -2.957007209750105E-8},
133 {0.19999954104423523, 1.5830993332061267E-10},
134 {-0.16624879837036133, -2.6033824355191673E-8}
135 };
136
137
138
139
140 private static final double[] SINE_TABLE_A =
141 {
142 +0.0d,
143 +0.1246747374534607d,
144 +0.24740394949913025d,
145 +0.366272509098053d,
146 +0.4794255495071411d,
147 +0.5850973129272461d,
148 +0.6816387176513672d,
149 +0.7675435543060303d,
150 +0.8414709568023682d,
151 +0.902267575263977d,
152 +0.9489846229553223d,
153 +0.9808930158615112d,
154 +0.9974949359893799d,
155 +0.9985313415527344d,
156 };
157
158
159 private static final double[] SINE_TABLE_B =
160 {
161 +0.0d,
162 -4.068233003401932E-9d,
163 +9.755392680573412E-9d,
164 +1.9987994582857286E-8d,
165 -1.0902938113007961E-8d,
166 -3.9986783938944604E-8d,
167 +4.23719669792332E-8d,
168 -5.207000323380292E-8d,
169 +2.800552834259E-8d,
170 +1.883511811213715E-8d,
171 -3.5997360512765566E-9d,
172 +4.116164446561962E-8d,
173 +5.0614674548127384E-8d,
174 -1.0129027912496858E-9d,
175 };
176
177
178 private static final double[] COSINE_TABLE_A =
179 {
180 +1.0d,
181 +0.9921976327896118d,
182 +0.9689123630523682d,
183 +0.9305076599121094d,
184 +0.8775825500488281d,
185 +0.8109631538391113d,
186 +0.7316888570785522d,
187 +0.6409968137741089d,
188 +0.5403022766113281d,
189 +0.4311765432357788d,
190 +0.3153223395347595d,
191 +0.19454771280288696d,
192 +0.07073719799518585d,
193 -0.05417713522911072d,
194 };
195
196
197 private static final double[] COSINE_TABLE_B =
198 {
199 +0.0d,
200 +3.4439717236742845E-8d,
201 +5.865827662008209E-8d,
202 -3.7999795083850525E-8d,
203 +1.184154459111628E-8d,
204 -3.43338934259355E-8d,
205 +1.1795268640216787E-8d,
206 +4.438921624363781E-8d,
207 +2.925681159240093E-8d,
208 -2.6437112632041807E-8d,
209 +2.2860509143963117E-8d,
210 -4.813899778443457E-9d,
211 +3.6725170580355583E-9d,
212 +2.0217439756338078E-10d,
213 };
214
215
216
217 private static final double[] TANGENT_TABLE_A =
218 {
219 +0.0d,
220 +0.1256551444530487d,
221 +0.25534194707870483d,
222 +0.3936265707015991d,
223 +0.5463024377822876d,
224 +0.7214844226837158d,
225 +0.9315965175628662d,
226 +1.1974215507507324d,
227 +1.5574076175689697d,
228 +2.092571258544922d,
229 +3.0095696449279785d,
230 +5.041914939880371d,
231 +14.101419448852539d,
232 -18.430862426757812d,
233 };
234
235
236 private static final double[] TANGENT_TABLE_B =
237 {
238 +0.0d,
239 -7.877917738262007E-9d,
240 -2.5857668567479893E-8d,
241 +5.2240336371356666E-9d,
242 +5.206150291559893E-8d,
243 +1.8307188599677033E-8d,
244 -5.7618793749770706E-8d,
245 +7.848361555046424E-8d,
246 +1.0708593250394448E-7d,
247 +1.7827257129423813E-8d,
248 +2.893485277253286E-8d,
249 +3.1660099222737955E-7d,
250 +4.983191803254889E-7d,
251 -3.356118100840571E-7d,
252 };
253
254
255 private static final long[] RECIP_2PI = {
256 (0x28be60dbL << 32) | 0x9391054aL,
257 (0x7f09d5f4L << 32) | 0x7d4d3770L,
258 (0x36d8a566L << 32) | 0x4f10e410L,
259 (0x7f9458eaL << 32) | 0xf7aef158L,
260 (0x6dc91b8eL << 32) | 0x909374b8L,
261 (0x01924bbaL << 32) | 0x82746487L,
262 (0x3f877ac7L << 32) | 0x2c4a69cfL,
263 (0xba208d7dL << 32) | 0x4baed121L,
264 (0x3a671c09L << 32) | 0xad17df90L,
265 (0x4e64758eL << 32) | 0x60d4ce7dL,
266 (0x272117e2L << 32) | 0xef7e4a0eL,
267 (0xc7fe25ffL << 32) | 0xf7816603L,
268 (0xfbcbc462L << 32) | 0xd6829b47L,
269 (0xdb4d9fb3L << 32) | 0xc9f2c26dL,
270 (0xd3d18fd9L << 32) | 0xa797fa8bL,
271 (0x5d49eeb1L << 32) | 0xfaf97c5eL,
272 (0xcf41ce7dL << 32) | 0xe294a4baL,
273 0x9afed7ecL << 32 };
274
275
276 private static final long[] PI_O_4_BITS = {
277 (0xc90fdaa2L << 32) | 0x2168c234L,
278 (0xc4c6628bL << 32) | 0x80dc1cd1L };
279
280
281
282
283
284 private static final double[]
285 EIGHTHS = {0, 0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875, 1.0, 1.125, 1.25, 1.375, 1.5, 1.625};
286
287
288 private static final double[] CBRTTWO = { 0.6299605249474366,
289 0.7937005259840998,
290 1.0,
291 1.2599210498948732,
292 1.5874010519681994 };
293
294
295
296
297
298
299
300
301
302
303
304
305 private static final long HEX_40000000 = 0x40000000L;
306
307
308 private static final long MASK_30BITS = -1L - (HEX_40000000 -1);
309
310
311 private static final int MASK_NON_SIGN_INT = 0x7fffffff;
312
313
314 private static final long MASK_NON_SIGN_LONG = 0x7fffffffffffffffl;
315
316
317 private static final long MASK_DOUBLE_EXPONENT = 0x7ff0000000000000L;
318
319
320 private static final long MASK_DOUBLE_MANTISSA = 0x000fffffffffffffL;
321
322
323 private static final long IMPLICIT_HIGH_BIT = 0x0010000000000000L;
324
325
326 private static final double TWO_POWER_52 = 4503599627370496.0;
327
328
329 private static final double F_1_3 = 1d / 3d;
330
331 private static final double F_1_5 = 1d / 5d;
332
333 private static final double F_1_7 = 1d / 7d;
334
335 private static final double F_1_9 = 1d / 9d;
336
337 private static final double F_1_11 = 1d / 11d;
338
339 private static final double F_1_13 = 1d / 13d;
340
341 private static final double F_1_15 = 1d / 15d;
342
343 private static final double F_1_17 = 1d / 17d;
344
345 private static final double F_3_4 = 3d / 4d;
346
347 private static final double F_15_16 = 15d / 16d;
348
349 private static final double F_13_14 = 13d / 14d;
350
351 private static final double F_11_12 = 11d / 12d;
352
353 private static final double F_9_10 = 9d / 10d;
354
355 private static final double F_7_8 = 7d / 8d;
356
357 private static final double F_5_6 = 5d / 6d;
358
359 private static final double F_1_2 = 1d / 2d;
360
361 private static final double F_1_4 = 1d / 4d;
362
363
364
365
366 private FastMath() {}
367
368
369
370
371
372
373
374
375
376
377 private static double doubleHighPart(double d) {
378 if (d > -Precision.SAFE_MIN && d < Precision.SAFE_MIN){
379 return d;
380 }
381 long xl = Double.doubleToRawLongBits(d);
382 xl &= MASK_30BITS;
383 return Double.longBitsToDouble(xl);
384 }
385
386
387
388
389
390
391 public static double sqrt(final double a) {
392 return Math.sqrt(a);
393 }
394
395
396
397
398
399 public static double cosh(double x) {
400 if (Double.isNaN(x)) {
401 return x;
402 }
403
404
405
406
407
408
409 if (x > 20) {
410 if (x >= LOG_MAX_VALUE) {
411
412 final double t = exp(0.5 * x);
413 return (0.5 * t) * t;
414 } else {
415 return 0.5 * exp(x);
416 }
417 } else if (x < -20) {
418 if (x <= -LOG_MAX_VALUE) {
419
420 final double t = exp(-0.5 * x);
421 return (0.5 * t) * t;
422 } else {
423 return 0.5 * exp(-x);
424 }
425 }
426
427 final double[] hiPrec = new double[2];
428 if (x < 0.0) {
429 x = -x;
430 }
431 exp(x, 0.0, hiPrec);
432
433 double ya = hiPrec[0] + hiPrec[1];
434 double yb = -(ya - hiPrec[0] - hiPrec[1]);
435
436 double temp = ya * HEX_40000000;
437 double yaa = ya + temp - temp;
438 double yab = ya - yaa;
439
440
441 double recip = 1.0/ya;
442 temp = recip * HEX_40000000;
443 double recipa = recip + temp - temp;
444 double recipb = recip - recipa;
445
446
447 recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
448
449 recipb += -yb * recip * recip;
450
451
452 temp = ya + recipa;
453 yb += -(temp - ya - recipa);
454 ya = temp;
455 temp = ya + recipb;
456 yb += -(temp - ya - recipb);
457 ya = temp;
458
459 double result = ya + yb;
460 result *= 0.5;
461 return result;
462 }
463
464
465
466
467
468 public static double sinh(double x) {
469 boolean negate = false;
470 if (Double.isNaN(x)) {
471 return x;
472 }
473
474
475
476
477
478
479 if (x > 20) {
480 if (x >= LOG_MAX_VALUE) {
481
482 final double t = exp(0.5 * x);
483 return (0.5 * t) * t;
484 } else {
485 return 0.5 * exp(x);
486 }
487 } else if (x < -20) {
488 if (x <= -LOG_MAX_VALUE) {
489
490 final double t = exp(-0.5 * x);
491 return (-0.5 * t) * t;
492 } else {
493 return -0.5 * exp(-x);
494 }
495 }
496
497 if (x == 0) {
498 return x;
499 }
500
501 if (x < 0.0) {
502 x = -x;
503 negate = true;
504 }
505
506 double[] hiPrec = new double[2];
507 double result;
508
509 if (x > 0.25) {
510 exp(x, 0.0, hiPrec);
511
512 double ya = hiPrec[0] + hiPrec[1];
513 double yb = -(ya - hiPrec[0] - hiPrec[1]);
514
515 double temp = ya * HEX_40000000;
516 double yaa = ya + temp - temp;
517 double yab = ya - yaa;
518
519
520 double recip = 1.0/ya;
521 temp = recip * HEX_40000000;
522 double recipa = recip + temp - temp;
523 double recipb = recip - recipa;
524
525
526 recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
527
528 recipb += -yb * recip * recip;
529
530 recipa = -recipa;
531 recipb = -recipb;
532
533
534 temp = ya + recipa;
535 yb += -(temp - ya - recipa);
536 ya = temp;
537 temp = ya + recipb;
538 yb += -(temp - ya - recipb);
539 ya = temp;
540
541 result = ya + yb;
542 result *= 0.5;
543 } else {
544 expm1(x, hiPrec);
545
546 double ya = hiPrec[0] + hiPrec[1];
547 double yb = -(ya - hiPrec[0] - hiPrec[1]);
548
549
550 double denom = 1.0 + ya;
551 double denomr = 1.0 / denom;
552 double denomb = -(denom - 1.0 - ya) + yb;
553 double ratio = ya * denomr;
554 double temp = ratio * HEX_40000000;
555 double ra = ratio + temp - temp;
556 double rb = ratio - ra;
557
558 temp = denom * HEX_40000000;
559 double za = denom + temp - temp;
560 double zb = denom - za;
561
562 rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr;
563
564
565 rb += yb*denomr;
566 rb += -ya * denomb * denomr * denomr;
567
568
569 temp = ya + ra;
570 yb += -(temp - ya - ra);
571 ya = temp;
572 temp = ya + rb;
573 yb += -(temp - ya - rb);
574 ya = temp;
575
576 result = ya + yb;
577 result *= 0.5;
578 }
579
580 if (negate) {
581 result = -result;
582 }
583
584 return result;
585 }
586
587
588
589
590
591
592
593 public static SinhCosh sinhCosh(double x) {
594 boolean negate = false;
595 if (Double.isNaN(x)) {
596 return new SinhCosh(x, x);
597 }
598
599
600
601
602
603
604
605 if (x > 20) {
606 final double e;
607 if (x >= LOG_MAX_VALUE) {
608
609 final double t = exp(0.5 * x);
610 e = (0.5 * t) * t;
611 } else {
612 e = 0.5 * exp(x);
613 }
614 return new SinhCosh(e, e);
615 } else if (x < -20) {
616 final double e;
617 if (x <= -LOG_MAX_VALUE) {
618
619 final double t = exp(-0.5 * x);
620 e = (-0.5 * t) * t;
621 } else {
622 e = -0.5 * exp(-x);
623 }
624 return new SinhCosh(e, -e);
625 }
626
627 if (x == 0) {
628 return new SinhCosh(x, 1.0);
629 }
630
631 if (x < 0.0) {
632 x = -x;
633 negate = true;
634 }
635
636 double[] hiPrec = new double[2];
637 double resultM;
638 double resultP;
639
640 if (x > 0.25) {
641 exp(x, 0.0, hiPrec);
642
643 final double ya = hiPrec[0] + hiPrec[1];
644 final double yb = -(ya - hiPrec[0] - hiPrec[1]);
645
646 double temp = ya * HEX_40000000;
647 double yaa = ya + temp - temp;
648 double yab = ya - yaa;
649
650
651 double recip = 1.0/ya;
652 temp = recip * HEX_40000000;
653 double recipa = recip + temp - temp;
654 double recipb = recip - recipa;
655
656
657 recipb += (1.0 - yaa*recipa - yaa*recipb - yab*recipa - yab*recipb) * recip;
658
659 recipb += -yb * recip * recip;
660
661
662 temp = ya - recipa;
663 double ybM = yb - (temp - ya + recipa);
664 double yaM = temp;
665 temp = yaM - recipb;
666 ybM += -(temp - yaM + recipb);
667 yaM = temp;
668 resultM = yaM + ybM;
669 resultM *= 0.5;
670
671
672 temp = ya + recipa;
673 double ybP = yb - (temp - ya - recipa);
674 double yaP = temp;
675 temp = yaP + recipb;
676 ybP += -(temp - yaP - recipb);
677 yaP = temp;
678 resultP = yaP + ybP;
679 resultP *= 0.5;
680
681 } else {
682 expm1(x, hiPrec);
683
684 final double ya = hiPrec[0] + hiPrec[1];
685 final double yb = -(ya - hiPrec[0] - hiPrec[1]);
686
687
688 double denom = 1.0 + ya;
689 double denomr = 1.0 / denom;
690 double denomb = -(denom - 1.0 - ya) + yb;
691 double ratio = ya * denomr;
692 double temp = ratio * HEX_40000000;
693 double ra = ratio + temp - temp;
694 double rb = ratio - ra;
695
696 temp = denom * HEX_40000000;
697 double za = denom + temp - temp;
698 double zb = denom - za;
699
700 rb += (ya - za*ra - za*rb - zb*ra - zb*rb) * denomr;
701
702
703 rb += yb*denomr;
704 rb += -ya * denomb * denomr * denomr;
705
706
707 temp = ya + ra;
708 double ybM = yb - (temp - ya - ra);
709 double yaM = temp;
710 temp = yaM + rb;
711 ybM += -(temp - yaM - rb);
712 yaM = temp;
713 resultM = yaM + ybM;
714 resultM *= 0.5;
715
716
717 temp = ya - ra;
718 double ybP = yb - (temp - ya + ra);
719 double yaP = temp;
720 temp = yaP - rb;
721 ybP += -(temp - yaP + rb);
722 yaP = temp;
723 resultP = yaP + ybP + 2;
724 resultP *= 0.5;
725 }
726
727 if (negate) {
728 resultM = -resultM;
729 }
730
731 return new SinhCosh(resultM, resultP);
732
733 }
734
735
736
737
738
739
740
741
742 public static <T extends CalculusFieldElement<T>> FieldSinhCosh<T> sinhCosh(T x) {
743 return x.sinhCosh();
744 }
745
746
747
748
749
750 public static double tanh(double x) {
751 boolean negate = false;
752
753 if (Double.isNaN(x)) {
754 return x;
755 }
756
757
758
759
760
761
762
763 if (x > 20.0) {
764 return 1.0;
765 }
766
767 if (x < -20) {
768 return -1.0;
769 }
770
771 if (x == 0) {
772 return x;
773 }
774
775 if (x < 0.0) {
776 x = -x;
777 negate = true;
778 }
779
780 double result;
781 if (x >= 0.5) {
782 double[] hiPrec = new double[2];
783
784 exp(x*2.0, 0.0, hiPrec);
785
786 double ya = hiPrec[0] + hiPrec[1];
787 double yb = -(ya - hiPrec[0] - hiPrec[1]);
788
789
790 double na = -1.0 + ya;
791 double nb = -(na + 1.0 - ya);
792 double temp = na + yb;
793 nb += -(temp - na - yb);
794 na = temp;
795
796
797 double da = 1.0 + ya;
798 double db = -(da - 1.0 - ya);
799 temp = da + yb;
800 db += -(temp - da - yb);
801 da = temp;
802
803 temp = da * HEX_40000000;
804 double daa = da + temp - temp;
805 double dab = da - daa;
806
807
808 double ratio = na/da;
809 temp = ratio * HEX_40000000;
810 double ratioa = ratio + temp - temp;
811 double ratiob = ratio - ratioa;
812
813
814 ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da;
815
816
817 ratiob += nb / da;
818
819 ratiob += -db * na / da / da;
820
821 result = ratioa + ratiob;
822 }
823 else {
824 double[] hiPrec = new double[2];
825
826 expm1(x*2.0, hiPrec);
827
828 double ya = hiPrec[0] + hiPrec[1];
829 double yb = -(ya - hiPrec[0] - hiPrec[1]);
830
831
832 double na = ya;
833 double nb = yb;
834
835
836 double da = 2.0 + ya;
837 double db = -(da - 2.0 - ya);
838 double temp = da + yb;
839 db += -(temp - da - yb);
840 da = temp;
841
842 temp = da * HEX_40000000;
843 double daa = da + temp - temp;
844 double dab = da - daa;
845
846
847 double ratio = na/da;
848 temp = ratio * HEX_40000000;
849 double ratioa = ratio + temp - temp;
850 double ratiob = ratio - ratioa;
851
852
853 ratiob += (na - daa*ratioa - daa*ratiob - dab*ratioa - dab*ratiob) / da;
854
855
856 ratiob += nb / da;
857
858 ratiob += -db * na / da / da;
859
860 result = ratioa + ratiob;
861 }
862
863 if (negate) {
864 result = -result;
865 }
866
867 return result;
868 }
869
870
871
872
873
874 public static double acosh(final double a) {
875 return FastMath.log(a + FastMath.sqrt(a * a - 1));
876 }
877
878
879
880
881
882 public static double asinh(double a) {
883 boolean negative = false;
884 if (a < 0) {
885 negative = true;
886 a = -a;
887 }
888
889 double absAsinh;
890 if (a > 0.167) {
891 absAsinh = FastMath.log(FastMath.sqrt(a * a + 1) + a);
892 } else {
893 final double a2 = a * a;
894 if (a > 0.097) {
895 absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * (F_1_9 - a2 * (F_1_11 - a2 * (F_1_13 - a2 * (F_1_15 - a2 * F_1_17 * F_15_16) * F_13_14) * F_11_12) * F_9_10) * F_7_8) * F_5_6) * F_3_4) * F_1_2);
896 } else if (a > 0.036) {
897 absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * (F_1_9 - a2 * (F_1_11 - a2 * F_1_13 * F_11_12) * F_9_10) * F_7_8) * F_5_6) * F_3_4) * F_1_2);
898 } else if (a > 0.0036) {
899 absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * F_1_9 * F_7_8) * F_5_6) * F_3_4) * F_1_2);
900 } else {
901 absAsinh = a * (1 - a2 * (F_1_3 - a2 * F_1_5 * F_3_4) * F_1_2);
902 }
903 }
904
905 return negative ? -absAsinh : absAsinh;
906 }
907
908
909
910
911
912 public static double atanh(double a) {
913 boolean negative = false;
914 if (a < 0) {
915 negative = true;
916 a = -a;
917 }
918
919 double absAtanh;
920 if (a > 0.15) {
921 absAtanh = 0.5 * FastMath.log((1 + a) / (1 - a));
922 } else {
923 final double a2 = a * a;
924 if (a > 0.087) {
925 absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * (F_1_9 + a2 * (F_1_11 + a2 * (F_1_13 + a2 * (F_1_15 + a2 * F_1_17))))))));
926 } else if (a > 0.031) {
927 absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * (F_1_9 + a2 * (F_1_11 + a2 * F_1_13))))));
928 } else if (a > 0.003) {
929 absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * F_1_9))));
930 } else {
931 absAtanh = a * (1 + a2 * (F_1_3 + a2 * F_1_5));
932 }
933 }
934
935 return negative ? -absAtanh : absAtanh;
936 }
937
938
939
940
941
942
943 public static double signum(final double a) {
944 return (a < 0.0) ? -1.0 : ((a > 0.0) ? 1.0 : a);
945 }
946
947
948
949
950
951
952 public static float signum(final float a) {
953 return (a < 0.0f) ? -1.0f : ((a > 0.0f) ? 1.0f : a);
954 }
955
956
957
958
959
960 public static double nextUp(final double a) {
961 return nextAfter(a, Double.POSITIVE_INFINITY);
962 }
963
964
965
966
967
968 public static float nextUp(final float a) {
969 return nextAfter(a, Float.POSITIVE_INFINITY);
970 }
971
972
973
974
975
976 public static double nextDown(final double a) {
977 return nextAfter(a, Double.NEGATIVE_INFINITY);
978 }
979
980
981
982
983
984 public static float nextDown(final float a) {
985 return nextAfter(a, Float.NEGATIVE_INFINITY);
986 }
987
988
989
990
991
992
993
994
995 public static int clamp(final int value, final int inf, final int sup) {
996 return max(inf, min(value, sup));
997 }
998
999
1000
1001
1002
1003
1004
1005
1006 public static long clamp(final long value, final long inf, final long sup) {
1007 return max(inf, min(value, sup));
1008 }
1009
1010
1011
1012
1013
1014
1015
1016
1017 public static int clamp(final long value, final int inf, final int sup) {
1018 return (int) max(inf, min(value, sup));
1019 }
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 public static float clamp(final float value, final float inf, final float sup) {
1032 return max(inf, min(value, sup));
1033 }
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045 public static double clamp(final double value, final double inf, final double sup) {
1046 return max(inf, min(value, sup));
1047 }
1048
1049
1050
1051
1052
1053 public static double random() {
1054 return Math.random();
1055 }
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077 public static double exp(double x) {
1078 return exp(x, 0.0, null);
1079 }
1080
1081
1082
1083
1084
1085
1086
1087
1088 private static double exp(double x, double extra, double[] hiPrec) {
1089 double intPartA;
1090 double intPartB;
1091 int intVal = (int) x;
1092
1093
1094
1095
1096
1097 if (x < 0.0) {
1098
1099
1100
1101 if (x < -746d) {
1102 if (hiPrec != null) {
1103 hiPrec[0] = 0.0;
1104 hiPrec[1] = 0.0;
1105 }
1106 return 0.0;
1107 }
1108
1109 if (intVal < -709) {
1110
1111 final double result = exp(x+40.19140625, extra, hiPrec) / 285040095144011776.0;
1112 if (hiPrec != null) {
1113 hiPrec[0] /= 285040095144011776.0;
1114 hiPrec[1] /= 285040095144011776.0;
1115 }
1116 return result;
1117 }
1118
1119 if (intVal == -709) {
1120
1121 final double result = exp(x+1.494140625, extra, hiPrec) / 4.455505956692756620;
1122 if (hiPrec != null) {
1123 hiPrec[0] /= 4.455505956692756620;
1124 hiPrec[1] /= 4.455505956692756620;
1125 }
1126 return result;
1127 }
1128
1129 intVal--;
1130
1131 } else {
1132 if (intVal > 709) {
1133 if (hiPrec != null) {
1134 hiPrec[0] = Double.POSITIVE_INFINITY;
1135 hiPrec[1] = 0.0;
1136 }
1137 return Double.POSITIVE_INFINITY;
1138 }
1139
1140 }
1141
1142 intPartA = ExpIntTable.EXP_INT_TABLE_A[EXP_INT_TABLE_MAX_INDEX+intVal];
1143 intPartB = ExpIntTable.EXP_INT_TABLE_B[EXP_INT_TABLE_MAX_INDEX+intVal];
1144
1145
1146
1147
1148
1149 final int intFrac = (int) ((x - intVal) * 1024.0);
1150 final double fracPartA = ExpFracTable.EXP_FRAC_TABLE_A[intFrac];
1151 final double fracPartB = ExpFracTable.EXP_FRAC_TABLE_B[intFrac];
1152
1153
1154
1155
1156
1157 final double epsilon = x - (intVal + intFrac / 1024.0);
1158
1159
1160
1161
1162
1163
1164
1165
1166 double z = 0.04168701738764507;
1167 z = z * epsilon + 0.1666666505023083;
1168 z = z * epsilon + 0.5000000000042687;
1169 z = z * epsilon + 1.0;
1170 z = z * epsilon + -3.940510424527919E-20;
1171
1172
1173
1174
1175
1176
1177 double tempA = intPartA * fracPartA;
1178 double tempB = intPartA * fracPartB + intPartB * fracPartA + intPartB * fracPartB;
1179
1180
1181
1182
1183
1184 final double tempC = tempB + tempA;
1185
1186
1187
1188 if (tempC == Double.POSITIVE_INFINITY) {
1189 if (hiPrec != null) {
1190 hiPrec[0] = Double.POSITIVE_INFINITY;
1191 hiPrec[1] = 0.0;
1192 }
1193 return Double.POSITIVE_INFINITY;
1194 }
1195
1196 final double result;
1197 if (extra != 0.0) {
1198 result = tempC*extra*z + tempC*extra + tempC*z + tempB + tempA;
1199 } else {
1200 result = tempC*z + tempB + tempA;
1201 }
1202
1203 if (hiPrec != null) {
1204
1205 hiPrec[0] = tempA;
1206 hiPrec[1] = tempC*extra*z + tempC*extra + tempC*z + tempB;
1207 }
1208
1209 return result;
1210 }
1211
1212
1213
1214
1215
1216 public static double expm1(double x) {
1217 return expm1(x, null);
1218 }
1219
1220
1221
1222
1223
1224
1225 private static double expm1(double x, double[] hiPrecOut) {
1226 if (Double.isNaN(x) || x == 0.0) {
1227 return x;
1228 }
1229
1230 if (x <= -1.0 || x >= 1.0) {
1231
1232
1233 double[] hiPrec = new double[2];
1234 exp(x, 0.0, hiPrec);
1235 if (x > 0.0) {
1236 return -1.0 + hiPrec[0] + hiPrec[1];
1237 } else {
1238 final double ra = -1.0 + hiPrec[0];
1239 double rb = -(ra + 1.0 - hiPrec[0]);
1240 rb += hiPrec[1];
1241 return ra + rb;
1242 }
1243 }
1244
1245 double baseA;
1246 double baseB;
1247 double epsilon;
1248 boolean negative = false;
1249
1250 if (x < 0.0) {
1251 x = -x;
1252 negative = true;
1253 }
1254
1255 {
1256 int intFrac = (int) (x * 1024.0);
1257 double tempA = ExpFracTable.EXP_FRAC_TABLE_A[intFrac] - 1.0;
1258 double tempB = ExpFracTable.EXP_FRAC_TABLE_B[intFrac];
1259
1260 double temp = tempA + tempB;
1261 tempB = -(temp - tempA - tempB);
1262 tempA = temp;
1263
1264 temp = tempA * HEX_40000000;
1265 baseA = tempA + temp - temp;
1266 baseB = tempB + (tempA - baseA);
1267
1268 epsilon = x - intFrac/1024.0;
1269 }
1270
1271
1272
1273 double zb = 0.008336750013465571;
1274 zb = zb * epsilon + 0.041666663879186654;
1275 zb = zb * epsilon + 0.16666666666745392;
1276 zb = zb * epsilon + 0.49999999999999994;
1277 zb *= epsilon;
1278 zb *= epsilon;
1279
1280 double za = epsilon;
1281 double temp = za + zb;
1282 zb = -(temp - za - zb);
1283 za = temp;
1284
1285 temp = za * HEX_40000000;
1286 temp = za + temp - temp;
1287 zb += za - temp;
1288 za = temp;
1289
1290
1291 double ya = za * baseA;
1292
1293 temp = ya + za * baseB;
1294 double yb = -(temp - ya - za * baseB);
1295 ya = temp;
1296
1297 temp = ya + zb * baseA;
1298 yb += -(temp - ya - zb * baseA);
1299 ya = temp;
1300
1301 temp = ya + zb * baseB;
1302 yb += -(temp - ya - zb*baseB);
1303 ya = temp;
1304
1305
1306
1307 temp = ya + baseA;
1308 yb += -(temp - baseA - ya);
1309 ya = temp;
1310
1311 temp = ya + za;
1312
1313 yb += -(temp - ya - za);
1314 ya = temp;
1315
1316 temp = ya + baseB;
1317
1318 yb += -(temp - ya - baseB);
1319 ya = temp;
1320
1321 temp = ya + zb;
1322
1323 yb += -(temp - ya - zb);
1324 ya = temp;
1325
1326 if (negative) {
1327
1328 double denom = 1.0 + ya;
1329 double denomr = 1.0 / denom;
1330 double denomb = -(denom - 1.0 - ya) + yb;
1331 double ratio = ya * denomr;
1332 temp = ratio * HEX_40000000;
1333 final double ra = ratio + temp - temp;
1334 double rb = ratio - ra;
1335
1336 temp = denom * HEX_40000000;
1337 za = denom + temp - temp;
1338 zb = denom - za;
1339
1340 rb += (ya - za * ra - za * rb - zb * ra - zb * rb) * denomr;
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351 rb += yb * denomr;
1352 rb += -ya * denomb * denomr * denomr;
1353
1354
1355 ya = -ra;
1356 yb = -rb;
1357 }
1358
1359 if (hiPrecOut != null) {
1360 hiPrecOut[0] = ya;
1361 hiPrecOut[1] = yb;
1362 }
1363
1364 return ya + yb;
1365 }
1366
1367
1368
1369
1370
1371
1372
1373 public static double log(final double x) {
1374 return log(x, null);
1375 }
1376
1377
1378
1379
1380
1381
1382
1383 private static double log(final double x, final double[] hiPrec) {
1384 if (x==0) {
1385 return Double.NEGATIVE_INFINITY;
1386 }
1387 long bits = Double.doubleToRawLongBits(x);
1388
1389
1390 if (((bits & 0x8000000000000000L) != 0 || Double.isNaN(x)) && x != 0.0) {
1391 if (hiPrec != null) {
1392 hiPrec[0] = Double.NaN;
1393 }
1394
1395 return Double.NaN;
1396 }
1397
1398
1399 if (x == Double.POSITIVE_INFINITY) {
1400 if (hiPrec != null) {
1401 hiPrec[0] = Double.POSITIVE_INFINITY;
1402 }
1403
1404 return Double.POSITIVE_INFINITY;
1405 }
1406
1407
1408 int exp = (int)(bits >> 52)-1023;
1409
1410 if ((bits & 0x7ff0000000000000L) == 0) {
1411
1412 if (x == 0) {
1413
1414 if (hiPrec != null) {
1415 hiPrec[0] = Double.NEGATIVE_INFINITY;
1416 }
1417
1418 return Double.NEGATIVE_INFINITY;
1419 }
1420
1421
1422 bits <<= 1;
1423 while ( (bits & 0x0010000000000000L) == 0) {
1424 --exp;
1425 bits <<= 1;
1426 }
1427 }
1428
1429
1430 if ((exp == -1 || exp == 0) && x < 1.01 && x > 0.99 && hiPrec == null) {
1431
1432
1433
1434
1435 double xa = x - 1.0;
1436 double tmp = xa * HEX_40000000;
1437 double aa = xa + tmp - tmp;
1438 double ab = xa - aa;
1439 xa = aa;
1440 double xb = ab;
1441
1442 final double[] lnCoef_last = LN_QUICK_COEF[LN_QUICK_COEF.length - 1];
1443 double ya = lnCoef_last[0];
1444 double yb = lnCoef_last[1];
1445
1446 for (int i = LN_QUICK_COEF.length - 2; i >= 0; i--) {
1447
1448 aa = ya * xa;
1449 ab = ya * xb + yb * xa + yb * xb;
1450
1451 tmp = aa * HEX_40000000;
1452 ya = aa + tmp - tmp;
1453 yb = aa - ya + ab;
1454
1455
1456 final double[] lnCoef_i = LN_QUICK_COEF[i];
1457 aa = ya + lnCoef_i[0];
1458 ab = yb + lnCoef_i[1];
1459
1460 tmp = aa * HEX_40000000;
1461 ya = aa + tmp - tmp;
1462 yb = aa - ya + ab;
1463 }
1464
1465
1466 aa = ya * xa;
1467 ab = ya * xb + yb * xa + yb * xb;
1468
1469 tmp = aa * HEX_40000000;
1470 ya = aa + tmp - tmp;
1471 yb = aa - ya + ab;
1472
1473 return ya + yb;
1474 }
1475
1476
1477 final double[] lnm = lnMant.LN_MANT[(int)((bits & 0x000ffc0000000000L) >> 42)];
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488 final double epsilon = (bits & 0x3ffffffffffL) / (TWO_POWER_52 + (bits & 0x000ffc0000000000L));
1489
1490 double lnza;
1491 double lnzb = 0.0;
1492
1493 if (hiPrec != null) {
1494
1495 double tmp = epsilon * HEX_40000000;
1496 double aa = epsilon + tmp - tmp;
1497 double ab = epsilon - aa;
1498 double xa = aa;
1499 double xb = ab;
1500
1501
1502 final double numer = bits & 0x3ffffffffffL;
1503 final double denom = TWO_POWER_52 + (bits & 0x000ffc0000000000L);
1504 aa = numer - xa*denom - xb * denom;
1505 xb += aa / denom;
1506
1507
1508 final double[] lnCoef_last = LN_HI_PREC_COEF[LN_HI_PREC_COEF.length-1];
1509 double ya = lnCoef_last[0];
1510 double yb = lnCoef_last[1];
1511
1512 for (int i = LN_HI_PREC_COEF.length - 2; i >= 0; i--) {
1513
1514 aa = ya * xa;
1515 ab = ya * xb + yb * xa + yb * xb;
1516
1517 tmp = aa * HEX_40000000;
1518 ya = aa + tmp - tmp;
1519 yb = aa - ya + ab;
1520
1521
1522 final double[] lnCoef_i = LN_HI_PREC_COEF[i];
1523 aa = ya + lnCoef_i[0];
1524 ab = yb + lnCoef_i[1];
1525
1526 tmp = aa * HEX_40000000;
1527 ya = aa + tmp - tmp;
1528 yb = aa - ya + ab;
1529 }
1530
1531
1532 aa = ya * xa;
1533 ab = ya * xb + yb * xa + yb * xb;
1534
1535
1536
1537
1538
1539
1540
1541 lnza = aa + ab;
1542 lnzb = -(lnza - aa - ab);
1543 } else {
1544
1545
1546 lnza = -0.16624882440418567;
1547 lnza = lnza * epsilon + 0.19999954120254515;
1548 lnza = lnza * epsilon + -0.2499999997677497;
1549 lnza = lnza * epsilon + 0.3333333333332802;
1550 lnza = lnza * epsilon + -0.5;
1551 lnza = lnza * epsilon + 1.0;
1552 lnza *= epsilon;
1553 }
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569 double a = LN_2_A*exp;
1570 double b = 0.0;
1571 double c = a+lnm[0];
1572 double d = -(c-a-lnm[0]);
1573 a = c;
1574 b += d;
1575
1576 c = a + lnza;
1577 d = -(c - a - lnza);
1578 a = c;
1579 b += d;
1580
1581 c = a + LN_2_B*exp;
1582 d = -(c - a - LN_2_B*exp);
1583 a = c;
1584 b += d;
1585
1586 c = a + lnm[1];
1587 d = -(c - a - lnm[1]);
1588 a = c;
1589 b += d;
1590
1591 c = a + lnzb;
1592 d = -(c - a - lnzb);
1593 a = c;
1594 b += d;
1595
1596 if (hiPrec != null) {
1597 hiPrec[0] = a;
1598 hiPrec[1] = b;
1599 }
1600
1601 return a + b;
1602 }
1603
1604
1605
1606
1607
1608
1609
1610 public static double log1p(final double x) {
1611 if (x == -1) {
1612 return Double.NEGATIVE_INFINITY;
1613 }
1614
1615 if (x == Double.POSITIVE_INFINITY) {
1616 return Double.POSITIVE_INFINITY;
1617 }
1618
1619 if (x > 1e-6 ||
1620 x < -1e-6) {
1621 final double xpa = 1 + x;
1622 final double xpb = -(xpa - 1 - x);
1623
1624 final double[] hiPrec = new double[2];
1625 final double lores = log(xpa, hiPrec);
1626 if (Double.isInfinite(lores)) {
1627 return lores;
1628 }
1629
1630
1631
1632 final double fx1 = xpb / xpa;
1633 final double epsilon = 0.5 * fx1 + 1;
1634 return epsilon * fx1 + hiPrec[1] + hiPrec[0];
1635 } else {
1636
1637 final double y = (x * F_1_3 - F_1_2) * x + 1;
1638 return y * x;
1639 }
1640 }
1641
1642
1643
1644
1645
1646 public static double log10(final double x) {
1647 final double[] hiPrec = new double[2];
1648
1649 final double lores = log(x, hiPrec);
1650 if (Double.isInfinite(lores)){
1651 return lores;
1652 }
1653
1654 final double tmp = hiPrec[0] * HEX_40000000;
1655 final double lna = hiPrec[0] + tmp - tmp;
1656 final double lnb = hiPrec[0] - lna + hiPrec[1];
1657
1658 final double rln10a = 0.4342944622039795;
1659 final double rln10b = 1.9699272335463627E-8;
1660
1661 return rln10b * lnb + rln10b * lna + rln10a * lnb + rln10a * lna;
1662 }
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679 public static double log(double base, double x) {
1680 return log(x) / log(base);
1681 }
1682
1683
1684
1685
1686
1687
1688
1689
1690 public static double pow(final double x, final double y) {
1691
1692 if (y == 0) {
1693
1694 return 1.0;
1695 } else {
1696
1697 final long yBits = Double.doubleToRawLongBits(y);
1698 final int yRawExp = (int) ((yBits & MASK_DOUBLE_EXPONENT) >> 52);
1699 final long yRawMantissa = yBits & MASK_DOUBLE_MANTISSA;
1700 final long xBits = Double.doubleToRawLongBits(x);
1701 final int xRawExp = (int) ((xBits & MASK_DOUBLE_EXPONENT) >> 52);
1702 final long xRawMantissa = xBits & MASK_DOUBLE_MANTISSA;
1703
1704 if (yRawExp > 1085) {
1705
1706
1707 if ((yRawExp == 2047 && yRawMantissa != 0) ||
1708 (xRawExp == 2047 && xRawMantissa != 0)) {
1709
1710 return Double.NaN;
1711 } else if (xRawExp == 1023 && xRawMantissa == 0) {
1712
1713 if (yRawExp == 2047) {
1714
1715 return Double.NaN;
1716 } else {
1717
1718 return 1.0;
1719 }
1720 } else {
1721
1722
1723
1724
1725
1726 if ((y > 0) ^ (xRawExp < 1023)) {
1727
1728
1729 return Double.POSITIVE_INFINITY;
1730 } else {
1731
1732
1733 return +0.0;
1734 }
1735 }
1736
1737 } else {
1738
1739
1740 if (yRawExp >= 1023) {
1741
1742 final long yFullMantissa = IMPLICIT_HIGH_BIT | yRawMantissa;
1743 if (yRawExp < 1075) {
1744
1745 final long integralMask = (-1L) << (1075 - yRawExp);
1746 if ((yFullMantissa & integralMask) == yFullMantissa) {
1747
1748 final long l = yFullMantissa >> (1075 - yRawExp);
1749 return FastMath.pow(x, (y < 0) ? -l : l);
1750 }
1751 } else {
1752
1753
1754 final long l = yFullMantissa << (yRawExp - 1075);
1755 return FastMath.pow(x, (y < 0) ? -l : l);
1756 }
1757 }
1758
1759
1760
1761 if (x == 0) {
1762
1763
1764 return y < 0 ? Double.POSITIVE_INFINITY : +0.0;
1765 } else if (xRawExp == 2047) {
1766 if (xRawMantissa == 0) {
1767
1768 return (y < 0) ? +0.0 : Double.POSITIVE_INFINITY;
1769 } else {
1770
1771 return Double.NaN;
1772 }
1773 } else if (x < 0) {
1774
1775 return Double.NaN;
1776 } else {
1777
1778
1779
1780
1781 final double tmp = y * HEX_40000000;
1782 final double ya = (y + tmp) - tmp;
1783 final double yb = y - ya;
1784
1785
1786 final double[] lns = new double[2];
1787 final double lores = log(x, lns);
1788 if (Double.isInfinite(lores)) {
1789 return lores;
1790 }
1791
1792 double lna = lns[0];
1793 double lnb = lns[1];
1794
1795
1796 final double tmp1 = lna * HEX_40000000;
1797 final double tmp2 = (lna + tmp1) - tmp1;
1798 lnb += lna - tmp2;
1799 lna = tmp2;
1800
1801
1802 final double aa = lna * ya;
1803 final double ab = lna * yb + lnb * ya + lnb * yb;
1804
1805 lna = aa+ab;
1806 lnb = -(lna - aa - ab);
1807
1808 double z = 1.0 / 120.0;
1809 z = z * lnb + (1.0 / 24.0);
1810 z = z * lnb + (1.0 / 6.0);
1811 z = z * lnb + 0.5;
1812 z = z * lnb + 1.0;
1813 z *= lnb;
1814
1815 return exp(lna, z, null);
1816
1817 }
1818 }
1819
1820 }
1821
1822 }
1823
1824
1825
1826
1827
1828
1829
1830
1831 public static double pow(double d, int e) {
1832 return pow(d, (long) e);
1833 }
1834
1835
1836
1837
1838
1839
1840
1841
1842 public static double pow(double d, long e) {
1843 if (e == 0) {
1844 return 1.0;
1845 } else if (e > 0) {
1846 return new Split(d).pow(e).full;
1847 } else {
1848 return new Split(d).reciprocal().pow(-e).full;
1849 }
1850 }
1851
1852
1853 private static class Split {
1854
1855
1856 public static final Split NAN = new Split(Double.NaN, 0);
1857
1858
1859 public static final Split POSITIVE_INFINITY = new Split(Double.POSITIVE_INFINITY, 0);
1860
1861
1862 public static final Split NEGATIVE_INFINITY = new Split(Double.NEGATIVE_INFINITY, 0);
1863
1864
1865 private final double full;
1866
1867
1868 private final double high;
1869
1870
1871 private final double low;
1872
1873
1874
1875
1876 Split(final double x) {
1877 full = x;
1878 high = Double.longBitsToDouble(Double.doubleToRawLongBits(x) & ((-1L) << 27));
1879 low = x - high;
1880 }
1881
1882
1883
1884
1885
1886 Split(final double high, final double low) {
1887 this(high == 0.0 ? (low == 0.0 && Double.doubleToRawLongBits(high) == Long.MIN_VALUE ? -0.0 : low) : high + low, high, low);
1888 }
1889
1890
1891
1892
1893
1894
1895 Split(final double full, final double high, final double low) {
1896 this.full = full;
1897 this.high = high;
1898 this.low = low;
1899 }
1900
1901
1902
1903
1904
1905 public Split multiply(final Split b) {
1906
1907 final Split mulBasic = new Split(full * b.full);
1908 final double mulError = low * b.low - (((mulBasic.full - high * b.high) - low * b.high) - high * b.low);
1909 return new Split(mulBasic.high, mulBasic.low + mulError);
1910 }
1911
1912
1913
1914
1915 public Split reciprocal() {
1916
1917 final double approximateInv = 1.0 / full;
1918 final Split splitInv = new Split(approximateInv);
1919
1920
1921
1922
1923 final Split product = multiply(splitInv);
1924 final double error = (product.high - 1) + product.low;
1925
1926
1927 return Double.isNaN(error) ? splitInv : new Split(splitInv.high, splitInv.low - error / full);
1928
1929 }
1930
1931
1932
1933
1934
1935 private Split pow(final long e) {
1936
1937
1938 Split result = new Split(1);
1939
1940
1941 Split d2p = new Split(full, high, low);
1942
1943 for (long p = e; p != 0; p >>>= 1) {
1944
1945 if ((p & 0x1) != 0) {
1946
1947 result = result.multiply(d2p);
1948 }
1949
1950
1951 d2p = d2p.multiply(d2p);
1952
1953 }
1954
1955 if (Double.isNaN(result.full)) {
1956 if (Double.isNaN(full)) {
1957 return Split.NAN;
1958 } else {
1959
1960
1961 if (FastMath.abs(full) < 1) {
1962 return new Split(FastMath.copySign(0.0, full), 0.0);
1963 } else if (full < 0 && (e & 0x1) == 1) {
1964 return Split.NEGATIVE_INFINITY;
1965 } else {
1966 return Split.POSITIVE_INFINITY;
1967 }
1968 }
1969 } else {
1970 return result;
1971 }
1972
1973 }
1974
1975 }
1976
1977
1978
1979
1980
1981
1982
1983 private static double polySine(final double x)
1984 {
1985 double x2 = x*x;
1986
1987 double p = 2.7553817452272217E-6;
1988 p = p * x2 + -1.9841269659586505E-4;
1989 p = p * x2 + 0.008333333333329196;
1990 p = p * x2 + -0.16666666666666666;
1991
1992
1993 p = p * x2 * x;
1994
1995 return p;
1996 }
1997
1998
1999
2000
2001
2002
2003
2004 private static double polyCosine(double x) {
2005 double x2 = x*x;
2006
2007 double p = 2.479773539153719E-5;
2008 p = p * x2 + -0.0013888888689039883;
2009 p = p * x2 + 0.041666666666621166;
2010 p = p * x2 + -0.49999999999999994;
2011 p *= x2;
2012
2013 return p;
2014 }
2015
2016
2017
2018
2019
2020
2021
2022
2023 private static double sinQ(double xa, double xb) {
2024 int idx = (int) ((xa * 8.0) + 0.5);
2025 final double epsilon = xa - EIGHTHS[idx];
2026
2027
2028 final double sintA = SINE_TABLE_A[idx];
2029 final double sintB = SINE_TABLE_B[idx];
2030 final double costA = COSINE_TABLE_A[idx];
2031 final double costB = COSINE_TABLE_B[idx];
2032
2033
2034 double sinEpsA = epsilon;
2035 double sinEpsB = polySine(epsilon);
2036 final double cosEpsA = 1.0;
2037 final double cosEpsB = polyCosine(epsilon);
2038
2039
2040 final double temp = sinEpsA * HEX_40000000;
2041 double temp2 = (sinEpsA + temp) - temp;
2042 sinEpsB += sinEpsA - temp2;
2043 sinEpsA = temp2;
2044
2045
2046 double result;
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069 double a = 0;
2070 double b = 0;
2071
2072 double t = sintA;
2073 double c = a + t;
2074 double d = -(c - a - t);
2075 a = c;
2076 b += d;
2077
2078 t = costA * sinEpsA;
2079 c = a + t;
2080 d = -(c - a - t);
2081 a = c;
2082 b += d;
2083
2084 b = b + sintA * cosEpsB + costA * sinEpsB;
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099 b = b + sintB + costB * sinEpsA + sintB * cosEpsB + costB * sinEpsB;
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126 if (xb != 0.0) {
2127 t = ((costA + costB) * (cosEpsA + cosEpsB) -
2128 (sintA + sintB) * (sinEpsA + sinEpsB)) * xb;
2129 c = a + t;
2130 d = -(c - a - t);
2131 a = c;
2132 b += d;
2133 }
2134
2135 result = a + b;
2136
2137 return result;
2138 }
2139
2140
2141
2142
2143
2144
2145
2146
2147 private static double cosQ(double xa, double xb) {
2148 final double pi2a = 1.5707963267948966;
2149 final double pi2b = 6.123233995736766E-17;
2150
2151 final double a = pi2a - xa;
2152 double b = -(a - pi2a + xa);
2153 b += pi2b - xb;
2154
2155 return sinQ(a, b);
2156 }
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166 private static double tanQ(double xa, double xb, boolean cotanFlag) {
2167
2168 int idx = (int) ((xa * 8.0) + 0.5);
2169 final double epsilon = xa - EIGHTHS[idx];
2170
2171
2172 final double sintA = SINE_TABLE_A[idx];
2173 final double sintB = SINE_TABLE_B[idx];
2174 final double costA = COSINE_TABLE_A[idx];
2175 final double costB = COSINE_TABLE_B[idx];
2176
2177
2178 double sinEpsA = epsilon;
2179 double sinEpsB = polySine(epsilon);
2180 final double cosEpsA = 1.0;
2181 final double cosEpsB = polyCosine(epsilon);
2182
2183
2184 double temp = sinEpsA * HEX_40000000;
2185 double temp2 = (sinEpsA + temp) - temp;
2186 sinEpsB += sinEpsA - temp2;
2187 sinEpsA = temp2;
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212 double a = 0;
2213 double b = 0;
2214
2215
2216 double t = sintA;
2217 double c = a + t;
2218 double d = -(c - a - t);
2219 a = c;
2220 b += d;
2221
2222 t = costA*sinEpsA;
2223 c = a + t;
2224 d = -(c - a - t);
2225 a = c;
2226 b += d;
2227
2228 b += sintA*cosEpsB + costA*sinEpsB;
2229 b += sintB + costB*sinEpsA + sintB*cosEpsB + costB*sinEpsB;
2230
2231 double sina = a + b;
2232 double sinb = -(sina - a - b);
2233
2234
2235
2236 a = 0.0;
2237 b = 0.0;
2238
2239 t = costA*cosEpsA;
2240 c = a + t;
2241 d = -(c - a - t);
2242 a = c;
2243 b += d;
2244
2245 t = -sintA*sinEpsA;
2246 c = a + t;
2247 d = -(c - a - t);
2248 a = c;
2249 b += d;
2250
2251 b += costB*cosEpsA + costA*cosEpsB + costB*cosEpsB;
2252 b -= sintB*sinEpsA + sintA*sinEpsB + sintB*sinEpsB;
2253
2254 double cosa = a + b;
2255 double cosb = -(cosa - a - b);
2256
2257 if (cotanFlag) {
2258 double tmp;
2259 tmp = cosa; cosa = sina; sina = tmp;
2260 tmp = cosb; cosb = sinb; sinb = tmp;
2261 }
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274 double est = sina/cosa;
2275
2276
2277 temp = est * HEX_40000000;
2278 double esta = (est + temp) - temp;
2279 double estb = est - esta;
2280
2281 temp = cosa * HEX_40000000;
2282 double cosaa = (cosa + temp) - temp;
2283 double cosab = cosa - cosaa;
2284
2285
2286 double err = (sina - esta*cosaa - esta*cosab - estb*cosaa - estb*cosab)/cosa;
2287 err += sinb/cosa;
2288 err += -sina * cosb / cosa / cosa;
2289
2290 if (xb != 0.0) {
2291
2292
2293 double xbadj = xb + est*est*xb;
2294 if (cotanFlag) {
2295 xbadj = -xbadj;
2296 }
2297
2298 err += xbadj;
2299 }
2300
2301 return est+err;
2302 }
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315 private static void reducePayneHanek(double x, double[] result)
2316 {
2317
2318 long inbits = Double.doubleToRawLongBits(x);
2319 int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
2320
2321
2322 inbits &= 0x000fffffffffffffL;
2323 inbits |= 0x0010000000000000L;
2324
2325
2326 exponent++;
2327 inbits <<= 11;
2328
2329
2330 long shpi0;
2331 long shpiA;
2332 long shpiB;
2333 int idx = exponent >> 6;
2334 int shift = exponent - (idx << 6);
2335
2336 if (shift != 0) {
2337 shpi0 = (idx == 0) ? 0 : (RECIP_2PI[idx-1] << shift);
2338 shpi0 |= RECIP_2PI[idx] >>> (64-shift);
2339 shpiA = (RECIP_2PI[idx] << shift) | (RECIP_2PI[idx+1] >>> (64-shift));
2340 shpiB = (RECIP_2PI[idx+1] << shift) | (RECIP_2PI[idx+2] >>> (64-shift));
2341 } else {
2342 shpi0 = (idx == 0) ? 0 : RECIP_2PI[idx-1];
2343 shpiA = RECIP_2PI[idx];
2344 shpiB = RECIP_2PI[idx+1];
2345 }
2346
2347
2348 long a = inbits >>> 32;
2349 long b = inbits & 0xffffffffL;
2350
2351 long c = shpiA >>> 32;
2352 long d = shpiA & 0xffffffffL;
2353
2354 long ac = a * c;
2355 long bd = b * d;
2356 long bc = b * c;
2357 long ad = a * d;
2358
2359 long prodB = bd + (ad << 32);
2360 long prodA = ac + (ad >>> 32);
2361
2362 boolean bita = (bd & 0x8000000000000000L) != 0;
2363 boolean bitb = (ad & 0x80000000L ) != 0;
2364 boolean bitsum = (prodB & 0x8000000000000000L) != 0;
2365
2366
2367 if ( (bita && bitb) ||
2368 ((bita || bitb) && !bitsum) ) {
2369 prodA++;
2370 }
2371
2372 bita = (prodB & 0x8000000000000000L) != 0;
2373 bitb = (bc & 0x80000000L ) != 0;
2374
2375 prodB += bc << 32;
2376 prodA += bc >>> 32;
2377
2378 bitsum = (prodB & 0x8000000000000000L) != 0;
2379
2380
2381 if ( (bita && bitb) ||
2382 ((bita || bitb) && !bitsum) ) {
2383 prodA++;
2384 }
2385
2386
2387 c = shpiB >>> 32;
2388 d = shpiB & 0xffffffffL;
2389 ac = a * c;
2390 bc = b * c;
2391 ad = a * d;
2392
2393
2394 ac += (bc + ad) >>> 32;
2395
2396 bita = (prodB & 0x8000000000000000L) != 0;
2397 bitb = (ac & 0x8000000000000000L ) != 0;
2398 prodB += ac;
2399 bitsum = (prodB & 0x8000000000000000L) != 0;
2400
2401 if ( (bita && bitb) ||
2402 ((bita || bitb) && !bitsum) ) {
2403 prodA++;
2404 }
2405
2406
2407 c = shpi0 >>> 32;
2408 d = shpi0 & 0xffffffffL;
2409
2410 bd = b * d;
2411 bc = b * c;
2412 ad = a * d;
2413
2414 prodA += bd + ((bc + ad) << 32);
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426 int intPart = (int)(prodA >>> 62);
2427
2428
2429 prodA <<= 2;
2430 prodA |= prodB >>> 62;
2431 prodB <<= 2;
2432
2433
2434 a = prodA >>> 32;
2435 b = prodA & 0xffffffffL;
2436
2437 c = PI_O_4_BITS[0] >>> 32;
2438 d = PI_O_4_BITS[0] & 0xffffffffL;
2439
2440 ac = a * c;
2441 bd = b * d;
2442 bc = b * c;
2443 ad = a * d;
2444
2445 long prod2B = bd + (ad << 32);
2446 long prod2A = ac + (ad >>> 32);
2447
2448 bita = (bd & 0x8000000000000000L) != 0;
2449 bitb = (ad & 0x80000000L ) != 0;
2450 bitsum = (prod2B & 0x8000000000000000L) != 0;
2451
2452
2453 if ( (bita && bitb) ||
2454 ((bita || bitb) && !bitsum) ) {
2455 prod2A++;
2456 }
2457
2458 bita = (prod2B & 0x8000000000000000L) != 0;
2459 bitb = (bc & 0x80000000L ) != 0;
2460
2461 prod2B += bc << 32;
2462 prod2A += bc >>> 32;
2463
2464 bitsum = (prod2B & 0x8000000000000000L) != 0;
2465
2466
2467 if ( (bita && bitb) ||
2468 ((bita || bitb) && !bitsum) ) {
2469 prod2A++;
2470 }
2471
2472
2473 c = PI_O_4_BITS[1] >>> 32;
2474 d = PI_O_4_BITS[1] & 0xffffffffL;
2475 ac = a * c;
2476 bc = b * c;
2477 ad = a * d;
2478
2479
2480 ac += (bc + ad) >>> 32;
2481
2482 bita = (prod2B & 0x8000000000000000L) != 0;
2483 bitb = (ac & 0x8000000000000000L ) != 0;
2484 prod2B += ac;
2485 bitsum = (prod2B & 0x8000000000000000L) != 0;
2486
2487 if ( (bita && bitb) ||
2488 ((bita || bitb) && !bitsum) ) {
2489 prod2A++;
2490 }
2491
2492
2493 a = prodB >>> 32;
2494 b = prodB & 0xffffffffL;
2495 c = PI_O_4_BITS[0] >>> 32;
2496 d = PI_O_4_BITS[0] & 0xffffffffL;
2497 ac = a * c;
2498 bc = b * c;
2499 ad = a * d;
2500
2501
2502 ac += (bc + ad) >>> 32;
2503
2504 bita = (prod2B & 0x8000000000000000L) != 0;
2505 bitb = (ac & 0x8000000000000000L ) != 0;
2506 prod2B += ac;
2507 bitsum = (prod2B & 0x8000000000000000L) != 0;
2508
2509 if ( (bita && bitb) ||
2510 ((bita || bitb) && !bitsum) ) {
2511 prod2A++;
2512 }
2513
2514
2515 double tmpA = (prod2A >>> 12) / TWO_POWER_52;
2516 double tmpB = (((prod2A & 0xfffL) << 40) + (prod2B >>> 24)) / TWO_POWER_52 / TWO_POWER_52;
2517
2518 double sumA = tmpA + tmpB;
2519 double sumB = -(sumA - tmpA - tmpB);
2520
2521
2522 result[0] = intPart;
2523 result[1] = sumA * 2.0;
2524 result[2] = sumB * 2.0;
2525 }
2526
2527
2528
2529
2530
2531
2532
2533 public static double sin(double x) {
2534 boolean negative = false;
2535 int quadrant = 0;
2536 double xa;
2537 double xb = 0.0;
2538
2539
2540 xa = x;
2541 if (x < 0) {
2542 negative = true;
2543 xa = -xa;
2544 }
2545
2546
2547 if (xa == 0.0) {
2548 long bits = Double.doubleToRawLongBits(x);
2549 if (bits < 0) {
2550 return -0.0;
2551 }
2552 return 0.0;
2553 }
2554
2555 if (xa != xa || xa == Double.POSITIVE_INFINITY) {
2556 return Double.NaN;
2557 }
2558
2559
2560 if (xa > 3294198.0) {
2561
2562
2563
2564 double[] reduceResults = new double[3];
2565 reducePayneHanek(xa, reduceResults);
2566 quadrant = ((int) reduceResults[0]) & 3;
2567 xa = reduceResults[1];
2568 xb = reduceResults[2];
2569 } else if (xa > 1.5707963267948966) {
2570 final CodyWaite cw = new CodyWaite(xa);
2571 quadrant = cw.getK() & 3;
2572 xa = cw.getRemA();
2573 xb = cw.getRemB();
2574 }
2575
2576 if (negative) {
2577 quadrant ^= 2;
2578 }
2579
2580 switch (quadrant) {
2581 case 0:
2582 return sinQ(xa, xb);
2583 case 1:
2584 return cosQ(xa, xb);
2585 case 2:
2586 return -sinQ(xa, xb);
2587 case 3:
2588 return -cosQ(xa, xb);
2589 default:
2590 return Double.NaN;
2591 }
2592 }
2593
2594
2595
2596
2597
2598
2599
2600 public static double cos(double x) {
2601 int quadrant = 0;
2602
2603
2604 double xa = x;
2605 if (x < 0) {
2606 xa = -xa;
2607 }
2608
2609 if (xa != xa || xa == Double.POSITIVE_INFINITY) {
2610 return Double.NaN;
2611 }
2612
2613
2614 double xb = 0;
2615 if (xa > 3294198.0) {
2616
2617
2618
2619 double[] reduceResults = new double[3];
2620 reducePayneHanek(xa, reduceResults);
2621 quadrant = ((int) reduceResults[0]) & 3;
2622 xa = reduceResults[1];
2623 xb = reduceResults[2];
2624 } else if (xa > 1.5707963267948966) {
2625 final CodyWaite cw = new CodyWaite(xa);
2626 quadrant = cw.getK() & 3;
2627 xa = cw.getRemA();
2628 xb = cw.getRemB();
2629 }
2630
2631
2632
2633
2634 switch (quadrant) {
2635 case 0:
2636 return cosQ(xa, xb);
2637 case 1:
2638 return -sinQ(xa, xb);
2639 case 2:
2640 return -cosQ(xa, xb);
2641 case 3:
2642 return sinQ(xa, xb);
2643 default:
2644 return Double.NaN;
2645 }
2646 }
2647
2648
2649
2650
2651
2652
2653
2654 public static SinCos sinCos(double x) {
2655 boolean negative = false;
2656 int quadrant = 0;
2657 double xa;
2658 double xb = 0.0;
2659
2660
2661 xa = x;
2662 if (x < 0) {
2663 negative = true;
2664 xa = -xa;
2665 }
2666
2667
2668 if (xa == 0.0) {
2669 long bits = Double.doubleToRawLongBits(x);
2670 if (bits < 0) {
2671 return new SinCos(-0.0, 1.0);
2672 }
2673 return new SinCos(0.0, 1.0);
2674 }
2675
2676 if (xa != xa || xa == Double.POSITIVE_INFINITY) {
2677 return new SinCos(Double.NaN, Double.NaN);
2678 }
2679
2680
2681 if (xa > 3294198.0) {
2682
2683
2684
2685 double[] reduceResults = new double[3];
2686 reducePayneHanek(xa, reduceResults);
2687 quadrant = ((int) reduceResults[0]) & 3;
2688 xa = reduceResults[1];
2689 xb = reduceResults[2];
2690 } else if (xa > 1.5707963267948966) {
2691 final CodyWaite cw = new CodyWaite(xa);
2692 quadrant = cw.getK() & 3;
2693 xa = cw.getRemA();
2694 xb = cw.getRemB();
2695 }
2696
2697 switch (quadrant) {
2698 case 0:
2699 return new SinCos(negative ? -sinQ(xa, xb) : sinQ(xa, xb), cosQ(xa, xb));
2700 case 1:
2701 return new SinCos(negative ? -cosQ(xa, xb) : cosQ(xa, xb), -sinQ(xa, xb));
2702 case 2:
2703 return new SinCos(negative ? sinQ(xa, xb) : -sinQ(xa, xb), -cosQ(xa, xb));
2704 case 3:
2705 return new SinCos(negative ? cosQ(xa, xb) : -cosQ(xa, xb), sinQ(xa, xb));
2706 default:
2707 return new SinCos(Double.NaN, Double.NaN);
2708 }
2709 }
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719 public static <T extends CalculusFieldElement<T>> FieldSinCos<T> sinCos(T x) {
2720 return x.sinCos();
2721 }
2722
2723
2724
2725
2726
2727
2728
2729 public static double tan(double x) {
2730 boolean negative = false;
2731 int quadrant = 0;
2732
2733
2734 double xa = x;
2735 if (x < 0) {
2736 negative = true;
2737 xa = -xa;
2738 }
2739
2740
2741 if (xa == 0.0) {
2742 long bits = Double.doubleToRawLongBits(x);
2743 if (bits < 0) {
2744 return -0.0;
2745 }
2746 return 0.0;
2747 }
2748
2749 if (xa != xa || xa == Double.POSITIVE_INFINITY) {
2750 return Double.NaN;
2751 }
2752
2753
2754 double xb = 0;
2755 if (xa > 3294198.0) {
2756
2757
2758
2759 double[] reduceResults = new double[3];
2760 reducePayneHanek(xa, reduceResults);
2761 quadrant = ((int) reduceResults[0]) & 3;
2762 xa = reduceResults[1];
2763 xb = reduceResults[2];
2764 } else if (xa > 1.5707963267948966) {
2765 final CodyWaite cw = new CodyWaite(xa);
2766 quadrant = cw.getK() & 3;
2767 xa = cw.getRemA();
2768 xb = cw.getRemB();
2769 }
2770
2771 if (xa > 1.5) {
2772
2773 final double pi2a = 1.5707963267948966;
2774 final double pi2b = 6.123233995736766E-17;
2775
2776 final double a = pi2a - xa;
2777 double b = -(a - pi2a + xa);
2778 b += pi2b - xb;
2779
2780 xa = a + b;
2781 xb = -(xa - a - b);
2782 quadrant ^= 1;
2783 negative ^= true;
2784 }
2785
2786 double result;
2787 if ((quadrant & 1) == 0) {
2788 result = tanQ(xa, xb, false);
2789 } else {
2790 result = -tanQ(xa, xb, true);
2791 }
2792
2793 if (negative) {
2794 result = -result;
2795 }
2796
2797 return result;
2798 }
2799
2800
2801
2802
2803
2804
2805 public static double atan(double x) {
2806 return atan(x, 0.0, false);
2807 }
2808
2809
2810
2811
2812
2813
2814
2815 private static double atan(double xa, double xb, boolean leftPlane) {
2816 if (xa == 0.0) {
2817 return leftPlane ? copySign(Math.PI, xa) : xa;
2818 }
2819
2820 final boolean negate;
2821 if (xa < 0) {
2822
2823 xa = -xa;
2824 xb = -xb;
2825 negate = true;
2826 } else {
2827 negate = false;
2828 }
2829
2830 if (xa > 1.633123935319537E16) {
2831 return (negate ^ leftPlane) ? (-Math.PI * F_1_2) : (Math.PI * F_1_2);
2832 }
2833
2834
2835 final int idx;
2836 if (xa < 1) {
2837 idx = (int) (((-1.7168146928204136 * xa * xa + 8.0) * xa) + 0.5);
2838 } else {
2839 final double oneOverXa = 1 / xa;
2840 idx = (int) (-((-1.7168146928204136 * oneOverXa * oneOverXa + 8.0) * oneOverXa) + 13.07);
2841 }
2842
2843 final double ttA = TANGENT_TABLE_A[idx];
2844 final double ttB = TANGENT_TABLE_B[idx];
2845
2846 double epsA = xa - ttA;
2847 double epsB = -(epsA - xa + ttA);
2848 epsB += xb - ttB;
2849
2850 double temp = epsA + epsB;
2851 epsB = -(temp - epsA - epsB);
2852 epsA = temp;
2853
2854
2855 temp = xa * HEX_40000000;
2856 double ya = xa + temp - temp;
2857 double yb = xb + xa - ya;
2858 xa = ya;
2859 xb += yb;
2860
2861
2862 if (idx == 0) {
2863
2864
2865 final double denom = 1d / (1d + (xa + xb) * (ttA + ttB));
2866
2867 ya = epsA * denom;
2868 yb = epsB * denom;
2869 } else {
2870 double temp2 = xa * ttA;
2871 double za = 1d + temp2;
2872 double zb = -(za - 1d - temp2);
2873 temp2 = xb * ttA + xa * ttB;
2874 temp = za + temp2;
2875 zb += -(temp - za - temp2);
2876 za = temp;
2877
2878 zb += xb * ttB;
2879 ya = epsA / za;
2880
2881 temp = ya * HEX_40000000;
2882 final double yaa = (ya + temp) - temp;
2883 final double yab = ya - yaa;
2884
2885 temp = za * HEX_40000000;
2886 final double zaa = (za + temp) - temp;
2887 final double zab = za - zaa;
2888
2889
2890 yb = (epsA - yaa * zaa - yaa * zab - yab * zaa - yab * zab) / za;
2891
2892 yb += -epsA * zb / za / za;
2893 yb += epsB / za;
2894 }
2895
2896
2897 epsA = ya;
2898 epsB = yb;
2899
2900
2901 final double epsA2 = epsA * epsA;
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912 yb = 0.07490822288864472;
2913 yb = yb * epsA2 - 0.09088450866185192;
2914 yb = yb * epsA2 + 0.11111095942313305;
2915 yb = yb * epsA2 - 0.1428571423679182;
2916 yb = yb * epsA2 + 0.19999999999923582;
2917 yb = yb * epsA2 - 0.33333333333333287;
2918 yb = yb * epsA2 * epsA;
2919
2920
2921 ya = epsA;
2922
2923 temp = ya + yb;
2924 yb = -(temp - ya - yb);
2925 ya = temp;
2926
2927
2928 yb += epsB / (1d + epsA * epsA);
2929
2930 final double eighths = EIGHTHS[idx];
2931
2932
2933 double za = eighths + ya;
2934 double zb = -(za - eighths - ya);
2935 temp = za + yb;
2936 zb += -(temp - za - yb);
2937 za = temp;
2938
2939 double result = za + zb;
2940
2941 if (leftPlane) {
2942
2943 final double resultb = -(result - za - zb);
2944 final double pia = 1.5707963267948966 * 2;
2945 final double pib = 6.123233995736766E-17 * 2;
2946
2947 za = pia - result;
2948 zb = -(za - pia + result);
2949 zb += pib - resultb;
2950
2951 result = za + zb;
2952 }
2953
2954
2955 if (negate ^ leftPlane) {
2956 result = -result;
2957 }
2958
2959 return result;
2960 }
2961
2962
2963
2964
2965
2966
2967
2968 public static double atan2(double y, double x) {
2969 if (Double.isNaN(x) || Double.isNaN(y)) {
2970 return Double.NaN;
2971 }
2972
2973 if (y == 0) {
2974 final double result = x * y;
2975 final double invx = 1d / x;
2976
2977 if (invx == 0) {
2978 if (x > 0) {
2979 return y;
2980 } else {
2981 return copySign(Math.PI, y);
2982 }
2983 }
2984
2985 if (x < 0 || invx < 0) {
2986 return copySign(Math.PI, y);
2987 } else {
2988 return result;
2989 }
2990 }
2991
2992
2993
2994 if (y == Double.POSITIVE_INFINITY) {
2995 if (x == Double.POSITIVE_INFINITY) {
2996 return Math.PI * F_1_4;
2997 }
2998
2999 if (x == Double.NEGATIVE_INFINITY) {
3000 return Math.PI * F_3_4;
3001 }
3002
3003 return Math.PI * F_1_2;
3004 }
3005
3006 if (y == Double.NEGATIVE_INFINITY) {
3007 if (x == Double.POSITIVE_INFINITY) {
3008 return -Math.PI * F_1_4;
3009 }
3010
3011 if (x == Double.NEGATIVE_INFINITY) {
3012 return -Math.PI * F_3_4;
3013 }
3014
3015 return -Math.PI * F_1_2;
3016 }
3017
3018 if (x == Double.POSITIVE_INFINITY) {
3019 return copySign(0d, y);
3020 }
3021
3022 if (x == Double.NEGATIVE_INFINITY)
3023 {
3024 return copySign(Math.PI, y);
3025 }
3026
3027
3028
3029 if (x == 0) {
3030 return copySign(Math.PI * F_1_2, y);
3031 }
3032
3033
3034 final double r = y / x;
3035 if (Double.isInfinite(r)) {
3036 return atan(r, 0, x < 0);
3037 }
3038
3039 double ra = doubleHighPart(r);
3040 double rb = r - ra;
3041
3042
3043 final double xa = doubleHighPart(x);
3044 final double xb = x - xa;
3045
3046 rb += (y - ra * xa - ra * xb - rb * xa - rb * xb) / x;
3047
3048 final double temp = ra + rb;
3049 rb = -(temp - ra - rb);
3050 ra = temp;
3051
3052 if (ra == 0) {
3053 ra = copySign(0d, y);
3054 }
3055
3056
3057 return atan(ra, rb, x < 0);
3058
3059 }
3060
3061
3062
3063
3064
3065 public static double asin(double x) {
3066 if (Double.isNaN(x)) {
3067 return Double.NaN;
3068 }
3069
3070 if (x > 1.0 || x < -1.0) {
3071 return Double.NaN;
3072 }
3073
3074 if (x == 1.0) {
3075 return Math.PI/2.0;
3076 }
3077
3078 if (x == -1.0) {
3079 return -Math.PI/2.0;
3080 }
3081
3082 if (x == 0.0) {
3083 return x;
3084 }
3085
3086
3087
3088
3089 double temp = x * HEX_40000000;
3090 final double xa = x + temp - temp;
3091 final double xb = x - xa;
3092
3093
3094 double ya = xa*xa;
3095 double yb = xa*xb*2.0 + xb*xb;
3096
3097
3098 ya = -ya;
3099 yb = -yb;
3100
3101 double za = 1.0 + ya;
3102 double zb = -(za - 1.0 - ya);
3103
3104 temp = za + yb;
3105 zb += -(temp - za - yb);
3106 za = temp;
3107
3108
3109 double y;
3110 y = sqrt(za);
3111 temp = y * HEX_40000000;
3112 ya = y + temp - temp;
3113 yb = y - ya;
3114
3115
3116 yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y);
3117
3118
3119 double dx = zb / (2.0*y);
3120
3121
3122 double r = x/y;
3123 temp = r * HEX_40000000;
3124 double ra = r + temp - temp;
3125 double rb = r - ra;
3126
3127 rb += (x - ra*ya - ra*yb - rb*ya - rb*yb) / y;
3128 rb += -x * dx / y / y;
3129
3130 temp = ra + rb;
3131 rb = -(temp - ra - rb);
3132 ra = temp;
3133
3134 return atan(ra, rb, false);
3135 }
3136
3137
3138
3139
3140
3141 public static double acos(double x) {
3142 if (Double.isNaN(x)) {
3143 return Double.NaN;
3144 }
3145
3146 if (x > 1.0 || x < -1.0) {
3147 return Double.NaN;
3148 }
3149
3150 if (x == -1.0) {
3151 return Math.PI;
3152 }
3153
3154 if (x == 1.0) {
3155 return 0.0;
3156 }
3157
3158 if (x == 0) {
3159 return Math.PI/2.0;
3160 }
3161
3162
3163
3164
3165 double temp = x * HEX_40000000;
3166 final double xa = x + temp - temp;
3167 final double xb = x - xa;
3168
3169
3170 double ya = xa*xa;
3171 double yb = xa*xb*2.0 + xb*xb;
3172
3173
3174 ya = -ya;
3175 yb = -yb;
3176
3177 double za = 1.0 + ya;
3178 double zb = -(za - 1.0 - ya);
3179
3180 temp = za + yb;
3181 zb += -(temp - za - yb);
3182 za = temp;
3183
3184
3185 double y = sqrt(za);
3186 temp = y * HEX_40000000;
3187 ya = y + temp - temp;
3188 yb = y - ya;
3189
3190
3191 yb += (za - ya*ya - 2*ya*yb - yb*yb) / (2.0*y);
3192
3193
3194 yb += zb / (2.0*y);
3195 y = ya+yb;
3196 yb = -(y - ya - yb);
3197
3198
3199 double r = y/x;
3200
3201
3202 if (Double.isInfinite(r)) {
3203 return Math.PI/2;
3204 }
3205
3206 double ra = doubleHighPart(r);
3207 double rb = r - ra;
3208
3209 rb += (y - ra*xa - ra*xb - rb*xa - rb*xb) / x;
3210 rb += yb / x;
3211
3212 temp = ra + rb;
3213 rb = -(temp - ra - rb);
3214 ra = temp;
3215
3216 return atan(ra, rb, x<0);
3217 }
3218
3219
3220
3221
3222
3223 public static double cbrt(double x) {
3224
3225 long inbits = Double.doubleToRawLongBits(x);
3226 int exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
3227 boolean subnormal = false;
3228
3229 if (exponent == -1023) {
3230 if (x == 0) {
3231 return x;
3232 }
3233
3234
3235 subnormal = true;
3236 x *= 1.8014398509481984E16;
3237 inbits = Double.doubleToRawLongBits(x);
3238 exponent = (int) ((inbits >> 52) & 0x7ff) - 1023;
3239 }
3240
3241 if (exponent == 1024) {
3242
3243 return x;
3244 }
3245
3246
3247 int exp3 = exponent / 3;
3248
3249
3250 double p2 = Double.longBitsToDouble((inbits & 0x8000000000000000L) |
3251 (long)(((exp3 + 1023) & 0x7ff)) << 52);
3252
3253
3254 final double mant = Double.longBitsToDouble((inbits & 0x000fffffffffffffL) | 0x3ff0000000000000L);
3255
3256
3257 double est = -0.010714690733195933;
3258 est = est * mant + 0.0875862700108075;
3259 est = est * mant + -0.3058015757857271;
3260 est = est * mant + 0.7249995199969751;
3261 est = est * mant + 0.5039018405998233;
3262
3263 est *= CBRTTWO[exponent % 3 + 2];
3264
3265
3266
3267
3268 final double xs = x / (p2*p2*p2);
3269 est += (xs - est*est*est) / (3*est*est);
3270 est += (xs - est*est*est) / (3*est*est);
3271
3272
3273 double temp = est * HEX_40000000;
3274 double ya = est + temp - temp;
3275 double yb = est - ya;
3276
3277 double za = ya * ya;
3278 double zb = ya * yb * 2.0 + yb * yb;
3279 temp = za * HEX_40000000;
3280 double temp2 = za + temp - temp;
3281 zb += za - temp2;
3282 za = temp2;
3283
3284 zb = za * yb + ya * zb + zb * yb;
3285 za *= ya;
3286
3287 double na = xs - za;
3288 double nb = -(na - xs + za);
3289 nb -= zb;
3290
3291 est += (na+nb)/(3*est*est);
3292
3293
3294 est *= p2;
3295
3296 if (subnormal) {
3297 est *= 3.814697265625E-6;
3298 }
3299
3300 return est;
3301 }
3302
3303
3304
3305
3306
3307
3308 public static double toRadians(double x)
3309 {
3310 if (Double.isInfinite(x) || x == 0.0) {
3311 return x;
3312 }
3313
3314
3315 final double facta = 0.01745329052209854;
3316 final double factb = 1.997844754509471E-9;
3317
3318 double xa = doubleHighPart(x);
3319 double xb = x - xa;
3320
3321 double result = xb * factb + xb * facta + xa * factb + xa * facta;
3322 if (result == 0) {
3323 result *= x;
3324 }
3325 return result;
3326 }
3327
3328
3329
3330
3331
3332
3333 public static double toDegrees(double x)
3334 {
3335 if (Double.isInfinite(x) || x == 0.0) {
3336 return x;
3337 }
3338
3339
3340 final double facta = 57.2957763671875;
3341 final double factb = 3.145894820876798E-6;
3342
3343 double xa = doubleHighPart(x);
3344 double xb = x - xa;
3345
3346 return xb * factb + xb * facta + xa * factb + xa * facta;
3347 }
3348
3349
3350
3351
3352
3353
3354 public static int abs(final int x) {
3355 final int i = x >>> 31;
3356 return (x ^ (~i + 1)) + i;
3357 }
3358
3359
3360
3361
3362
3363
3364 public static long abs(final long x) {
3365 final long l = x >>> 63;
3366
3367
3368
3369
3370 return (x ^ (~l + 1)) + l;
3371 }
3372
3373
3374
3375
3376
3377
3378
3379 public static int absExact(final int x) {
3380 if (x == Integer.MIN_VALUE) {
3381 throw new ArithmeticException();
3382 }
3383 return abs(x);
3384 }
3385
3386
3387
3388
3389
3390
3391
3392 public static long absExact(final long x) {
3393 if (x == Long.MIN_VALUE) {
3394 throw new ArithmeticException();
3395 }
3396 return abs(x);
3397 }
3398
3399
3400
3401
3402
3403
3404
3405 public static float abs(final float x) {
3406 return Float.intBitsToFloat(MASK_NON_SIGN_INT & Float.floatToRawIntBits(x));
3407 }
3408
3409
3410
3411
3412
3413
3414 public static double abs(double x) {
3415 return Double.longBitsToDouble(MASK_NON_SIGN_LONG & Double.doubleToRawLongBits(x));
3416 }
3417
3418
3419
3420
3421
3422
3423
3424 public static int negateExact(final int x) {
3425 if (x == Integer.MIN_VALUE) {
3426 throw new ArithmeticException();
3427 }
3428 return -x;
3429 }
3430
3431
3432
3433
3434
3435
3436
3437 public static long negateExact(final long x) {
3438 if (x == Long.MIN_VALUE) {
3439 throw new ArithmeticException();
3440 }
3441 return -x;
3442 }
3443
3444
3445
3446
3447
3448
3449 public static double ulp(double x) {
3450 if (Double.isInfinite(x)) {
3451 return Double.POSITIVE_INFINITY;
3452 }
3453 return abs(x - Double.longBitsToDouble(Double.doubleToRawLongBits(x) ^ 1));
3454 }
3455
3456
3457
3458
3459
3460
3461 public static float ulp(float x) {
3462 if (Float.isInfinite(x)) {
3463 return Float.POSITIVE_INFINITY;
3464 }
3465 return abs(x - Float.intBitsToFloat(Float.floatToRawIntBits(x) ^ 1));
3466 }
3467
3468
3469
3470
3471
3472
3473
3474 public static double scalb(final double d, final int n) {
3475
3476
3477 if ((n > -1023) && (n < 1024)) {
3478 return d * Double.longBitsToDouble(((long) (n + 1023)) << 52);
3479 }
3480
3481
3482 if (Double.isNaN(d) || Double.isInfinite(d) || (d == 0)) {
3483 return d;
3484 }
3485 if (n < -2098) {
3486 return (d > 0) ? 0.0 : -0.0;
3487 }
3488 if (n > 2097) {
3489 return (d > 0) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
3490 }
3491
3492
3493 final long bits = Double.doubleToRawLongBits(d);
3494 final long sign = bits & 0x8000000000000000L;
3495 int exponent = ((int) (bits >>> 52)) & 0x7ff;
3496 long mantissa = bits & 0x000fffffffffffffL;
3497
3498
3499 int scaledExponent = exponent + n;
3500
3501 if (n < 0) {
3502
3503 if (scaledExponent > 0) {
3504
3505 return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
3506 } else if (scaledExponent > -53) {
3507
3508
3509
3510 mantissa |= 1L << 52;
3511
3512
3513 final long mostSignificantLostBit = mantissa & (1L << (-scaledExponent));
3514 mantissa >>>= 1 - scaledExponent;
3515 if (mostSignificantLostBit != 0) {
3516
3517 mantissa++;
3518 }
3519 return Double.longBitsToDouble(sign | mantissa);
3520
3521 } else {
3522
3523 return (sign == 0L) ? 0.0 : -0.0;
3524 }
3525 } else {
3526
3527 if (exponent == 0) {
3528
3529
3530 while ((mantissa >>> 52) != 1) {
3531 mantissa <<= 1;
3532 --scaledExponent;
3533 }
3534 ++scaledExponent;
3535 mantissa &= 0x000fffffffffffffL;
3536
3537 if (scaledExponent < 2047) {
3538 return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
3539 } else {
3540 return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
3541 }
3542
3543 } else if (scaledExponent < 2047) {
3544 return Double.longBitsToDouble(sign | (((long) scaledExponent) << 52) | mantissa);
3545 } else {
3546 return (sign == 0L) ? Double.POSITIVE_INFINITY : Double.NEGATIVE_INFINITY;
3547 }
3548 }
3549
3550 }
3551
3552
3553
3554
3555
3556
3557
3558 public static float scalb(final float f, final int n) {
3559
3560
3561 if ((n > -127) && (n < 128)) {
3562 return f * Float.intBitsToFloat((n + 127) << 23);
3563 }
3564
3565
3566 if (Float.isNaN(f) || Float.isInfinite(f) || (f == 0f)) {
3567 return f;
3568 }
3569 if (n < -277) {
3570 return (f > 0) ? 0.0f : -0.0f;
3571 }
3572 if (n > 276) {
3573 return (f > 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
3574 }
3575
3576
3577 final int bits = Float.floatToIntBits(f);
3578 final int sign = bits & 0x80000000;
3579 int exponent = (bits >>> 23) & 0xff;
3580 int mantissa = bits & 0x007fffff;
3581
3582
3583 int scaledExponent = exponent + n;
3584
3585 if (n < 0) {
3586
3587 if (scaledExponent > 0) {
3588
3589 return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
3590 } else if (scaledExponent > -24) {
3591
3592
3593
3594 mantissa |= 1 << 23;
3595
3596
3597 final int mostSignificantLostBit = mantissa & (1 << (-scaledExponent));
3598 mantissa >>>= 1 - scaledExponent;
3599 if (mostSignificantLostBit != 0) {
3600
3601 mantissa++;
3602 }
3603 return Float.intBitsToFloat(sign | mantissa);
3604
3605 } else {
3606
3607 return (sign == 0) ? 0.0f : -0.0f;
3608 }
3609 } else {
3610
3611 if (exponent == 0) {
3612
3613
3614 while ((mantissa >>> 23) != 1) {
3615 mantissa <<= 1;
3616 --scaledExponent;
3617 }
3618 ++scaledExponent;
3619 mantissa &= 0x007fffff;
3620
3621 if (scaledExponent < 255) {
3622 return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
3623 } else {
3624 return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
3625 }
3626
3627 } else if (scaledExponent < 255) {
3628 return Float.intBitsToFloat(sign | (scaledExponent << 23) | mantissa);
3629 } else {
3630 return (sign == 0) ? Float.POSITIVE_INFINITY : Float.NEGATIVE_INFINITY;
3631 }
3632 }
3633
3634 }
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671 public static double nextAfter(double d, double direction) {
3672
3673
3674 if (Double.isNaN(d) || Double.isNaN(direction)) {
3675 return Double.NaN;
3676 } else if (d == direction) {
3677 return direction;
3678 } else if (Double.isInfinite(d)) {
3679 return (d < 0) ? -Double.MAX_VALUE : Double.MAX_VALUE;
3680 } else if (d == 0) {
3681 return (direction < 0) ? -Double.MIN_VALUE : Double.MIN_VALUE;
3682 }
3683
3684
3685
3686 final long bits = Double.doubleToRawLongBits(d);
3687 final long sign = bits & 0x8000000000000000L;
3688 if ((direction < d) ^ (sign == 0L)) {
3689 return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) + 1));
3690 } else {
3691 return Double.longBitsToDouble(sign | ((bits & 0x7fffffffffffffffL) - 1));
3692 }
3693
3694 }
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729 public static float nextAfter(final float f, final double direction) {
3730
3731
3732 if (Double.isNaN(f) || Double.isNaN(direction)) {
3733 return Float.NaN;
3734 } else if (f == direction) {
3735 return (float) direction;
3736 } else if (Float.isInfinite(f)) {
3737 return (f < 0f) ? -Float.MAX_VALUE : Float.MAX_VALUE;
3738 } else if (f == 0f) {
3739 return (direction < 0) ? -Float.MIN_VALUE : Float.MIN_VALUE;
3740 }
3741
3742
3743
3744 final int bits = Float.floatToIntBits(f);
3745 final int sign = bits & 0x80000000;
3746 if ((direction < f) ^ (sign == 0)) {
3747 return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) + 1));
3748 } else {
3749 return Float.intBitsToFloat(sign | ((bits & 0x7fffffff) - 1));
3750 }
3751
3752 }
3753
3754
3755
3756
3757
3758 public static double floor(double x) {
3759 long y;
3760
3761 if (Double.isNaN(x)) {
3762 return x;
3763 }
3764
3765 if (x >= TWO_POWER_52 || x <= -TWO_POWER_52) {
3766 return x;
3767 }
3768
3769 y = (long) x;
3770 if (x < 0 && y != x) {
3771 y--;
3772 }
3773
3774 if (y == 0) {
3775 return x*y;
3776 }
3777
3778 return y;
3779 }
3780
3781
3782
3783
3784
3785 public static double ceil(double x) {
3786 double y;
3787
3788 if (Double.isNaN(x)) {
3789 return x;
3790 }
3791
3792 y = floor(x);
3793 if (y == x) {
3794 return y;
3795 }
3796
3797 y += 1.0;
3798
3799 if (y == 0) {
3800 return x*y;
3801 }
3802
3803 return y;
3804 }
3805
3806
3807
3808
3809
3810 public static double rint(double x) {
3811 double y = floor(x);
3812 double d = x - y;
3813
3814 if (d > 0.5) {
3815 if (y == -1.0) {
3816 return -0.0;
3817 }
3818 return y+1.0;
3819 }
3820 if (d < 0.5) {
3821 return y;
3822 }
3823
3824
3825 long z = (long) y;
3826 return (z & 1) == 0 ? y : y + 1.0;
3827 }
3828
3829
3830
3831
3832
3833 public static long round(double x) {
3834 final long bits = Double.doubleToRawLongBits(x);
3835 final int biasedExp = ((int)(bits>>52)) & 0x7ff;
3836
3837
3838 final int shift = (52 - 1 + Double.MAX_EXPONENT) - biasedExp;
3839 if ((shift & -64) == 0) {
3840
3841 long extendedMantissa = 0x0010000000000000L | (bits & 0x000fffffffffffffL);
3842 if (bits < 0) {
3843 extendedMantissa = -extendedMantissa;
3844 }
3845
3846
3847
3848 return ((extendedMantissa >> shift) + 1L) >> 1;
3849 } else {
3850
3851 return (long) x;
3852 }
3853 }
3854
3855
3856
3857
3858
3859 public static int round(final float x) {
3860 final int bits = Float.floatToRawIntBits(x);
3861 final int biasedExp = (bits>>23) & 0xff;
3862
3863
3864 final int shift = (23 - 1 + Float.MAX_EXPONENT) - biasedExp;
3865 if ((shift & -32) == 0) {
3866
3867 int extendedMantissa = 0x00800000 | (bits & 0x007fffff);
3868 if (bits < 0) {
3869 extendedMantissa = -extendedMantissa;
3870 }
3871
3872
3873
3874 return ((extendedMantissa >> shift) + 1) >> 1;
3875 } else {
3876
3877 return (int) x;
3878 }
3879 }
3880
3881
3882
3883
3884
3885
3886 public static int min(final int a, final int b) {
3887 return (a <= b) ? a : b;
3888 }
3889
3890
3891
3892
3893
3894
3895 public static long min(final long a, final long b) {
3896 return (a <= b) ? a : b;
3897 }
3898
3899
3900
3901
3902
3903
3904 public static float min(final float a, final float b) {
3905 if (a > b) {
3906 return b;
3907 }
3908 if (a < b) {
3909 return a;
3910 }
3911
3912 if (a != b) {
3913 return Float.NaN;
3914 }
3915
3916
3917 int bits = Float.floatToRawIntBits(a);
3918 if (bits == 0x80000000) {
3919 return a;
3920 }
3921 return b;
3922 }
3923
3924
3925
3926
3927
3928
3929 public static double min(final double a, final double b) {
3930 if (a > b) {
3931 return b;
3932 }
3933 if (a < b) {
3934 return a;
3935 }
3936
3937 if (a != b) {
3938 return Double.NaN;
3939 }
3940
3941
3942 long bits = Double.doubleToRawLongBits(a);
3943 if (bits == 0x8000000000000000L) {
3944 return a;
3945 }
3946 return b;
3947 }
3948
3949
3950
3951
3952
3953
3954 public static int max(final int a, final int b) {
3955 return (a <= b) ? b : a;
3956 }
3957
3958
3959
3960
3961
3962
3963 public static long max(final long a, final long b) {
3964 return (a <= b) ? b : a;
3965 }
3966
3967
3968
3969
3970
3971
3972 public static float max(final float a, final float b) {
3973 if (a > b) {
3974 return a;
3975 }
3976 if (a < b) {
3977 return b;
3978 }
3979
3980 if (a != b) {
3981 return Float.NaN;
3982 }
3983
3984
3985 int bits = Float.floatToRawIntBits(a);
3986 if (bits == 0x80000000) {
3987 return b;
3988 }
3989 return a;
3990 }
3991
3992
3993
3994
3995
3996
3997 public static double max(final double a, final double b) {
3998 if (a > b) {
3999 return a;
4000 }
4001 if (a < b) {
4002 return b;
4003 }
4004
4005 if (a != b) {
4006 return Double.NaN;
4007 }
4008
4009
4010 long bits = Double.doubleToRawLongBits(a);
4011 if (bits == 0x8000000000000000L) {
4012 return b;
4013 }
4014 return a;
4015 }
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031 public static double hypot(final double x, final double y) {
4032 if (Double.isInfinite(x) || Double.isInfinite(y)) {
4033 return Double.POSITIVE_INFINITY;
4034 } else if (Double.isNaN(x) || Double.isNaN(y)) {
4035 return Double.NaN;
4036 } else {
4037
4038 final int expX = getExponent(x);
4039 final int expY = getExponent(y);
4040 if (expX > expY + 27) {
4041
4042 return abs(x);
4043 } else if (expY > expX + 27) {
4044
4045 return abs(y);
4046 } else {
4047
4048
4049 final int middleExp = (expX + expY) / 2;
4050
4051
4052 final double scaledX = scalb(x, -middleExp);
4053 final double scaledY = scalb(y, -middleExp);
4054
4055
4056 final double scaledH = sqrt(scaledX * scaledX + scaledY * scaledY);
4057
4058
4059 return scalb(scaledH, middleExp);
4060
4061 }
4062
4063 }
4064 }
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086 public static double IEEEremainder(final double dividend, final double divisor) {
4087 if (getExponent(dividend) == 1024 || getExponent(divisor) == 1024 || divisor == 0.0) {
4088
4089 if (Double.isInfinite(divisor) && !Double.isInfinite(dividend)) {
4090 return dividend;
4091 } else {
4092 return Double.NaN;
4093 }
4094 } else {
4095
4096 final double n = FastMath.rint(dividend / divisor);
4097 final double remainder = Double.isInfinite(n) ? 0.0 : dividend - divisor * n;
4098 return (remainder == 0) ? FastMath.copySign(remainder, dividend) : remainder;
4099 }
4100 }
4101
4102
4103
4104
4105
4106
4107 public static int toIntExact(final long n) throws MathRuntimeException {
4108 if (n < Integer.MIN_VALUE || n > Integer.MAX_VALUE) {
4109 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW);
4110 }
4111 return (int) n;
4112 }
4113
4114
4115
4116
4117
4118
4119 public static int incrementExact(final int n) throws MathRuntimeException {
4120
4121 if (n == Integer.MAX_VALUE) {
4122 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, n, 1);
4123 }
4124
4125 return n + 1;
4126
4127 }
4128
4129
4130
4131
4132
4133
4134 public static long incrementExact(final long n) throws MathRuntimeException {
4135
4136 if (n == Long.MAX_VALUE) {
4137 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, n, 1);
4138 }
4139
4140 return n + 1;
4141
4142 }
4143
4144
4145
4146
4147
4148
4149 public static int decrementExact(final int n) throws MathRuntimeException {
4150
4151 if (n == Integer.MIN_VALUE) {
4152 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
4153 }
4154
4155 return n - 1;
4156
4157 }
4158
4159
4160
4161
4162
4163
4164 public static long decrementExact(final long n) throws MathRuntimeException {
4165
4166 if (n == Long.MIN_VALUE) {
4167 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, n, 1);
4168 }
4169
4170 return n - 1;
4171
4172 }
4173
4174
4175
4176
4177
4178
4179
4180 public static int addExact(final int a, final int b) throws MathRuntimeException {
4181
4182
4183 final int sum = a + b;
4184
4185
4186 if ((a ^ b) >= 0 && (sum ^ b) < 0) {
4187 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, a, b);
4188 }
4189
4190 return sum;
4191
4192 }
4193
4194
4195
4196
4197
4198
4199
4200 public static long addExact(final long a, final long b) throws MathRuntimeException {
4201
4202
4203 final long sum = a + b;
4204
4205
4206 if ((a ^ b) >= 0 && (sum ^ b) < 0) {
4207 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_ADDITION, a, b);
4208 }
4209
4210 return sum;
4211
4212 }
4213
4214
4215
4216
4217
4218
4219
4220 public static int subtractExact(final int a, final int b) {
4221
4222
4223 final int sub = a - b;
4224
4225
4226 if ((a ^ b) < 0 && (sub ^ b) >= 0) {
4227 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, a, b);
4228 }
4229
4230 return sub;
4231
4232 }
4233
4234
4235
4236
4237
4238
4239
4240 public static long subtractExact(final long a, final long b) {
4241
4242
4243 final long sub = a - b;
4244
4245
4246 if ((a ^ b) < 0 && (sub ^ b) >= 0) {
4247 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_SUBTRACTION, a, b);
4248 }
4249
4250 return sub;
4251
4252 }
4253
4254
4255
4256
4257
4258
4259
4260 public static int multiplyExact(final int a, final int b) {
4261 if (((b > 0) && (a > Integer.MAX_VALUE / b || a < Integer.MIN_VALUE / b)) ||
4262 ((b < -1) && (a > Integer.MIN_VALUE / b || a < Integer.MAX_VALUE / b)) ||
4263 ((b == -1) && (a == Integer.MIN_VALUE))) {
4264 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
4265 }
4266 return a * b;
4267 }
4268
4269
4270
4271
4272
4273
4274
4275
4276 public static long multiplyExact(final long a, final int b) {
4277 return multiplyExact(a, (long) b);
4278 }
4279
4280
4281
4282
4283
4284
4285
4286 public static long multiplyExact(final long a, final long b) {
4287 if (((b > 0l) && (a > Long.MAX_VALUE / b || a < Long.MIN_VALUE / b)) ||
4288 ((b < -1l) && (a > Long.MIN_VALUE / b || a < Long.MAX_VALUE / b)) ||
4289 ((b == -1l) && (a == Long.MIN_VALUE))) {
4290 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_MULTIPLICATION, a, b);
4291 }
4292 return a * b;
4293 }
4294
4295
4296
4297
4298
4299
4300
4301 public static long multiplyFull(final int a, final int b) {
4302 return ((long) a) * ((long) b);
4303 }
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319 public static long multiplyHigh(final long a, final long b) {
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329 final long tobeRemoved = ((a < 0) ? b : 0) + ((b < 0) ? a : 0);
4330
4331 return unsignedMultiplyHigh(a, b) - tobeRemoved;
4332
4333 }
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349 public static long unsignedMultiplyHigh(final long a, final long b) {
4350
4351
4352 final long aHigh = a >>> 32;
4353 final long aLow = a & 0xFFFFFFFFl;
4354 final long bHigh = b >>> 32;
4355 final long bLow = b & 0xFFFFFFFFl;
4356
4357
4358 final long hh = aHigh * bHigh;
4359 final long hl1 = aHigh * bLow;
4360 final long hl2 = aLow * bHigh;
4361 final long ll = aLow * bLow;
4362
4363
4364 final long hlHigh = (hl1 >>> 32) + (hl2 >>> 32);
4365 final long hlLow = (hl1 & 0xFFFFFFFFl) + (hl2 & 0xFFFFFFFFl);
4366 final long carry = (hlLow + (ll >>> 32)) >>> 32;
4367
4368 return hh + hlHigh + carry;
4369
4370 }
4371
4372
4373
4374
4375
4376
4377
4378
4379 public static int divideExact(final int x, final int y) {
4380 if (y == 0) {
4381 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4382 }
4383 if (y == -1 && x == Integer.MIN_VALUE) {
4384 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, x, y);
4385 }
4386 return x / y;
4387 }
4388
4389
4390
4391
4392
4393
4394
4395
4396 public static long divideExact(final long x, final long y) {
4397 if (y == 0l) {
4398 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4399 }
4400 if (y == -1l && x == Long.MIN_VALUE) {
4401 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, x, y);
4402 }
4403 return x / y;
4404 }
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418 public static int ceilDiv(final int a, final int b) throws MathRuntimeException {
4419
4420 if (b == 0) {
4421 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4422 }
4423
4424 final int m = a % b;
4425 if ((a ^ b) < 0 || m == 0) {
4426
4427 return a / b;
4428 } else {
4429
4430 return (a / b) + 1;
4431 }
4432
4433 }
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447 public static int ceilDivExact(final int a, final int b) throws MathRuntimeException {
4448
4449 if (a == Integer.MIN_VALUE && b == -1) {
4450 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
4451 }
4452
4453 return ceilDiv(a, b);
4454
4455 }
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469 public static long ceilDiv(final long a, final long b) throws MathRuntimeException {
4470
4471 if (b == 0l) {
4472 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4473 }
4474
4475 final long m = a % b;
4476 if ((a ^ b) < 0 || m == 0l) {
4477
4478 return a / b;
4479 } else {
4480
4481 return (a / b) + 1l;
4482 }
4483
4484 }
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498 public static long ceilDivExact(final long a, final long b) throws MathRuntimeException {
4499
4500 if (a == Long.MIN_VALUE && b == -1l) {
4501 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
4502 }
4503
4504 return ceilDiv(a, b);
4505
4506 }
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520 public static long ceilDiv(final long a, final int b) throws MathRuntimeException {
4521 return ceilDiv(a, (long) b);
4522 }
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536 public static int ceilMod(final int a, final int b) throws MathRuntimeException {
4537
4538 if (b == 0) {
4539 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4540 }
4541
4542 final int m = a % b;
4543 if ((a ^ b) < 0 || m == 0) {
4544
4545 return m;
4546 } else {
4547
4548 return m - b;
4549 }
4550
4551 }
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565 public static int ceilMod(final long a, final int b) throws MathRuntimeException {
4566 return (int) ceilMod(a, (long) b);
4567 }
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581 public static long ceilMod(final long a, final long b) throws MathRuntimeException {
4582
4583 if (b == 0l) {
4584 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4585 }
4586
4587 final long m = a % b;
4588 if ((a ^ b) < 0l || m == 0l) {
4589
4590 return m;
4591 } else {
4592
4593 return m - b;
4594 }
4595
4596 }
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610 public static int floorDiv(final int a, final int b) throws MathRuntimeException {
4611
4612 if (b == 0) {
4613 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4614 }
4615
4616 final int m = a % b;
4617 if ((a ^ b) >= 0 || m == 0) {
4618
4619 return a / b;
4620 } else {
4621
4622 return (a / b) - 1;
4623 }
4624
4625 }
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640 public static int floorDivExact(final int a, final int b) throws MathRuntimeException {
4641
4642 if (a == Integer.MIN_VALUE && b == -1) {
4643 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
4644 }
4645
4646 return floorDiv(a, b);
4647
4648 }
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663 public static long floorDiv(final long a, final int b) throws MathRuntimeException {
4664 return floorDiv(a, (long) b);
4665 }
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679 public static long floorDiv(final long a, final long b) throws MathRuntimeException {
4680
4681 if (b == 0l) {
4682 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4683 }
4684
4685 final long m = a % b;
4686 if ((a ^ b) >= 0l || m == 0l) {
4687
4688 return a / b;
4689 } else {
4690
4691 return (a / b) - 1l;
4692 }
4693
4694 }
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709 public static long floorDivExact(final long a, final long b) throws MathRuntimeException {
4710
4711 if (a == Long.MIN_VALUE && b == -1l) {
4712 throw new MathRuntimeException(LocalizedCoreFormats.OVERFLOW_IN_FRACTION, a, b);
4713 }
4714
4715 return floorDiv(a, b);
4716
4717 }
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731 public static int floorMod(final int a, final int b) throws MathRuntimeException {
4732
4733 if (b == 0) {
4734 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4735 }
4736
4737 final int m = a % b;
4738 if ((a ^ b) >= 0 || m == 0) {
4739
4740 return m;
4741 } else {
4742
4743 return b + m;
4744 }
4745
4746 }
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761 public static int floorMod(final long a, final int b) {
4762 return (int) floorMod(a, (long) b);
4763 }
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777 public static long floorMod(final long a, final long b) {
4778
4779 if (b == 0l) {
4780 throw new MathRuntimeException(LocalizedCoreFormats.ZERO_DENOMINATOR);
4781 }
4782
4783 final long m = a % b;
4784 if ((a ^ b) >= 0l || m == 0l) {
4785
4786 return m;
4787 } else {
4788
4789 return b + m;
4790 }
4791
4792 }
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802 public static double copySign(double magnitude, double sign){
4803
4804
4805
4806
4807 final long m = Double.doubleToRawLongBits(magnitude);
4808 final long s = Double.doubleToRawLongBits(sign);
4809 if ((m ^ s) >= 0) {
4810 return magnitude;
4811 }
4812 return -magnitude;
4813 }
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823 public static float copySign(float magnitude, float sign){
4824
4825
4826
4827
4828 final int m = Float.floatToRawIntBits(magnitude);
4829 final int s = Float.floatToRawIntBits(sign);
4830 if ((m ^ s) >= 0) {
4831 return magnitude;
4832 }
4833 return -magnitude;
4834 }
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845 public static int getExponent(final double d) {
4846
4847 return (int) ((Double.doubleToRawLongBits(d) >>> 52) & 0x7ff) - 1023;
4848 }
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859 public static int getExponent(final float f) {
4860
4861 return ((Float.floatToRawIntBits(f) >>> 23) & 0xff) - 127;
4862 }
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882 public static double fma(final double a, final double b, final double c) {
4883 return MathArrays.linearCombination(a, b, 1.0, c);
4884 }
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903 public static float fma(final float a, final float b, final float c) {
4904 return (float) MathArrays.linearCombination(a, b, 1.0, c);
4905 }
4906
4907
4908
4909
4910
4911
4912
4913 public static <T extends CalculusFieldElement<T>> T sqrt(final T a) {
4914 return a.sqrt();
4915 }
4916
4917
4918
4919
4920
4921
4922
4923 public static <T extends CalculusFieldElement<T>> T cosh(final T x) {
4924 return x.cosh();
4925 }
4926
4927
4928
4929
4930
4931
4932
4933 public static <T extends CalculusFieldElement<T>> T sinh(final T x) {
4934 return x.sinh();
4935 }
4936
4937
4938
4939
4940
4941
4942
4943 public static <T extends CalculusFieldElement<T>> T tanh(final T x) {
4944 return x.tanh();
4945 }
4946
4947
4948
4949
4950
4951
4952
4953 public static <T extends CalculusFieldElement<T>> T acosh(final T a) {
4954 return a.acosh();
4955 }
4956
4957
4958
4959
4960
4961
4962
4963 public static <T extends CalculusFieldElement<T>> T asinh(final T a) {
4964 return a.asinh();
4965 }
4966
4967
4968
4969
4970
4971
4972
4973 public static <T extends CalculusFieldElement<T>> T atanh(final T a) {
4974 return a.atanh();
4975 }
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986 public static <T extends CalculusFieldElement<T>> T sign(final T a) {
4987 return a.sign();
4988 }
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012 public static <T extends CalculusFieldElement<T>> T exp(final T x) {
5013 return x.exp();
5014 }
5015
5016
5017
5018
5019
5020
5021
5022 public static <T extends CalculusFieldElement<T>> T expm1(final T x) {
5023 return x.expm1();
5024 }
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034 public static <T extends CalculusFieldElement<T>> T log(final T x) {
5035 return x.log();
5036 }
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046 public static <T extends CalculusFieldElement<T>> T log1p(final T x) {
5047 return x.log1p();
5048 }
5049
5050
5051
5052
5053
5054
5055
5056 public static <T extends CalculusFieldElement<T>> T log10(final T x) {
5057 return x.log10();
5058 }
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069 public static <T extends CalculusFieldElement<T>> T pow(final T x, final T y) {
5070 return x.pow(y);
5071 }
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082 public static <T extends CalculusFieldElement<T>> T pow(final T x, final double y) {
5083 return x.pow(y);
5084 }
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095 public static <T extends CalculusFieldElement<T>> T pow(T d, int e) {
5096 return d.pow(e);
5097 }
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107 public static <T extends CalculusFieldElement<T>> T sin(final T x) {
5108 return x.sin();
5109 }
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119 public static <T extends CalculusFieldElement<T>> T cos(final T x) {
5120 return x.cos();
5121 }
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131 public static <T extends CalculusFieldElement<T>> T tan(final T x) {
5132 return x.tan();
5133 }
5134
5135
5136
5137
5138
5139
5140
5141
5142 public static <T extends CalculusFieldElement<T>> T atan(final T x) {
5143 return x.atan();
5144 }
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154 public static <T extends CalculusFieldElement<T>> T atan2(final T y, final T x) {
5155 return y.atan2(x);
5156 }
5157
5158
5159
5160
5161
5162
5163
5164 public static <T extends CalculusFieldElement<T>> T asin(final T x) {
5165 return x.asin();
5166 }
5167
5168
5169
5170
5171
5172
5173
5174 public static <T extends CalculusFieldElement<T>> T acos(final T x) {
5175 return x.acos();
5176 }
5177
5178
5179
5180
5181
5182
5183
5184 public static <T extends CalculusFieldElement<T>> T cbrt(final T x) {
5185 return x.cbrt();
5186 }
5187
5188
5189
5190
5191
5192
5193
5194
5195 public static <T extends CalculusFieldElement<T>> double norm(final T x) {
5196 return x.norm();
5197 }
5198
5199
5200
5201
5202
5203
5204
5205
5206 public static <T extends CalculusFieldElement<T>> T abs(final T x) {
5207 return x.abs();
5208 }
5209
5210
5211
5212
5213
5214
5215
5216 public static <T extends CalculusFieldElement<T>> T toRadians(T x) {
5217 return x.toRadians();
5218 }
5219
5220
5221
5222
5223
5224
5225
5226 public static <T extends CalculusFieldElement<T>> T toDegrees(T x) {
5227 return x.toDegrees();
5228 }
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238 public static <T extends CalculusFieldElement<T>> T scalb(final T d, final int n) {
5239 return d.scalb(n);
5240 }
5241
5242
5243
5244
5245
5246
5247
5248
5249 public static <T extends CalculusFieldElement<T>> T ulp(final T x) {
5250 if (Double.isInfinite(x.getReal())) {
5251 return x.newInstance(Double.POSITIVE_INFINITY);
5252 }
5253 return x.ulp();
5254 }
5255
5256
5257
5258
5259
5260
5261
5262 public static <T extends CalculusFieldElement<T>> T floor(final T x) {
5263 return x.floor();
5264 }
5265
5266
5267
5268
5269
5270
5271
5272 public static <T extends CalculusFieldElement<T>> T ceil(final T x) {
5273 return x.ceil();
5274 }
5275
5276
5277
5278
5279
5280
5281
5282 public static <T extends CalculusFieldElement<T>> T rint(final T x) {
5283 return x.rint();
5284 }
5285
5286
5287
5288
5289
5290
5291
5292 public static <T extends CalculusFieldElement<T>> long round(final T x) {
5293 return x.round();
5294 }
5295
5296
5297
5298
5299
5300
5301
5302
5303 public static <T extends CalculusFieldElement<T>> T min(final T a, final T b) {
5304 final double aR = a.getReal();
5305 final double bR = b.getReal();
5306 if (aR < bR) {
5307 return a;
5308 } else if (bR < aR) {
5309 return b;
5310 } else {
5311
5312 return Double.isNaN(aR) ? a : b;
5313 }
5314 }
5315
5316
5317
5318
5319
5320
5321
5322
5323 public static <T extends CalculusFieldElement<T>> T min(final T a, final double b) {
5324 final double aR = a.getReal();
5325 if (aR < b) {
5326 return a;
5327 } else if (b < aR) {
5328 return a.getField().getZero().add(b);
5329 } else {
5330
5331 return Double.isNaN(aR) ? a : a.getField().getZero().add(b);
5332 }
5333 }
5334
5335
5336
5337
5338
5339
5340
5341
5342 public static <T extends CalculusFieldElement<T>> T max(final T a, final T b) {
5343 final double aR = a.getReal();
5344 final double bR = b.getReal();
5345 if (aR < bR) {
5346 return b;
5347 } else if (bR < aR) {
5348 return a;
5349 } else {
5350
5351 return Double.isNaN(aR) ? a : b;
5352 }
5353 }
5354
5355
5356
5357
5358
5359
5360
5361
5362 public static <T extends CalculusFieldElement<T>> T max(final T a, final double b) {
5363 final double aR = a.getReal();
5364 if (aR < b) {
5365 return a.getField().getZero().add(b);
5366 } else if (b < aR) {
5367 return a;
5368 } else {
5369
5370 return Double.isNaN(aR) ? a : a.getField().getZero().add(b);
5371 }
5372 }
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390 public static <T extends CalculusFieldElement<T>> T hypot(final T x, final T y) {
5391 return x.hypot(y);
5392 }
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416 public static <T extends CalculusFieldElement<T>> T IEEEremainder(final T dividend, final double divisor) {
5417 return dividend.remainder(divisor);
5418 }
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442 public static <T extends CalculusFieldElement<T>> T IEEEremainder(final T dividend, final T divisor) {
5443 return dividend.remainder(divisor);
5444 }
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456 public static <T extends CalculusFieldElement<T>> T copySign(T magnitude, T sign) {
5457 return magnitude.copySign(sign);
5458 }
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470 public static <T extends CalculusFieldElement<T>> T copySign(T magnitude, double sign) {
5471 return magnitude.copySign(sign);
5472 }
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494 private static class ExpIntTable {
5495
5496
5497
5498 private static final double[] EXP_INT_TABLE_A;
5499
5500
5501
5502 private static final double[] EXP_INT_TABLE_B;
5503
5504 static {
5505 if (RECOMPUTE_TABLES_AT_RUNTIME) {
5506 EXP_INT_TABLE_A = new double[FastMath.EXP_INT_TABLE_LEN];
5507 EXP_INT_TABLE_B = new double[FastMath.EXP_INT_TABLE_LEN];
5508
5509 final double[] tmp = new double[2];
5510 final double[] recip = new double[2];
5511
5512
5513 for (int i = 0; i < FastMath.EXP_INT_TABLE_MAX_INDEX; i++) {
5514 FastMathCalc.expint(i, tmp);
5515 EXP_INT_TABLE_A[i + FastMath.EXP_INT_TABLE_MAX_INDEX] = tmp[0];
5516 EXP_INT_TABLE_B[i + FastMath.EXP_INT_TABLE_MAX_INDEX] = tmp[1];
5517
5518 if (i != 0) {
5519
5520 FastMathCalc.splitReciprocal(tmp, recip);
5521 EXP_INT_TABLE_A[FastMath.EXP_INT_TABLE_MAX_INDEX - i] = recip[0];
5522 EXP_INT_TABLE_B[FastMath.EXP_INT_TABLE_MAX_INDEX - i] = recip[1];
5523 }
5524 }
5525 } else {
5526 EXP_INT_TABLE_A = FastMathLiteralArrays.loadExpIntA();
5527 EXP_INT_TABLE_B = FastMathLiteralArrays.loadExpIntB();
5528 }
5529 }
5530 }
5531
5532
5533 private static class ExpFracTable {
5534
5535
5536
5537
5538 private static final double[] EXP_FRAC_TABLE_A;
5539
5540
5541
5542 private static final double[] EXP_FRAC_TABLE_B;
5543
5544 static {
5545 if (RECOMPUTE_TABLES_AT_RUNTIME) {
5546 EXP_FRAC_TABLE_A = new double[FastMath.EXP_FRAC_TABLE_LEN];
5547 EXP_FRAC_TABLE_B = new double[FastMath.EXP_FRAC_TABLE_LEN];
5548
5549 final double[] tmp = new double[2];
5550
5551
5552 final double factor = 1d / (EXP_FRAC_TABLE_LEN - 1);
5553 for (int i = 0; i < EXP_FRAC_TABLE_A.length; i++) {
5554 FastMathCalc.slowexp(i * factor, tmp);
5555 EXP_FRAC_TABLE_A[i] = tmp[0];
5556 EXP_FRAC_TABLE_B[i] = tmp[1];
5557 }
5558 } else {
5559 EXP_FRAC_TABLE_A = FastMathLiteralArrays.loadExpFracA();
5560 EXP_FRAC_TABLE_B = FastMathLiteralArrays.loadExpFracB();
5561 }
5562 }
5563 }
5564
5565
5566 private static class lnMant {
5567
5568 private static final double[][] LN_MANT;
5569
5570 static {
5571 if (RECOMPUTE_TABLES_AT_RUNTIME) {
5572 LN_MANT = new double[FastMath.LN_MANT_LEN][];
5573
5574
5575 for (int i = 0; i < LN_MANT.length; i++) {
5576 final double d = Double.longBitsToDouble( (((long) i) << 42) | 0x3ff0000000000000L );
5577 LN_MANT[i] = FastMathCalc.slowLog(d);
5578 }
5579 } else {
5580 LN_MANT = FastMathLiteralArrays.loadLnMant();
5581 }
5582 }
5583 }
5584
5585
5586 private static class CodyWaite {
5587
5588 private final int finalK;
5589
5590 private final double finalRemA;
5591
5592 private final double finalRemB;
5593
5594
5595
5596
5597 CodyWaite(double xa) {
5598
5599
5600 int k = (int)(xa * 0.6366197723675814);
5601
5602
5603 double remA;
5604 double remB;
5605 while (true) {
5606 double a = -k * 1.570796251296997;
5607 remA = xa + a;
5608 remB = -(remA - xa - a);
5609
5610 a = -k * 7.549789948768648E-8;
5611 double b = remA;
5612 remA = a + b;
5613 remB += -(remA - b - a);
5614
5615 a = -k * 6.123233995736766E-17;
5616 b = remA;
5617 remA = a + b;
5618 remB += -(remA - b - a);
5619
5620 if (remA > 0) {
5621 break;
5622 }
5623
5624
5625
5626
5627 --k;
5628 }
5629
5630 this.finalK = k;
5631 this.finalRemA = remA;
5632 this.finalRemB = remB;
5633 }
5634
5635
5636
5637
5638 int getK() {
5639 return finalK;
5640 }
5641
5642
5643
5644 double getRemA() {
5645 return finalRemA;
5646 }
5647
5648
5649
5650 double getRemB() {
5651 return finalRemB;
5652 }
5653 }
5654
5655 }