This source file includes following definitions.
- decode
- multiply
- FUNC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #if ! defined USE_LONG_DOUBLE
20 # include <config.h>
21 #endif
22
23
24 #include <math.h>
25
26 #include <limits.h>
27 #include <stdbool.h>
28 #include <stdlib.h>
29
30 #if HAVE_FEGETROUND
31 # include <fenv.h>
32 #endif
33
34 #include "float+.h"
35 #include "integer_length.h"
36 #include "verify.h"
37
38 #ifdef USE_LONG_DOUBLE
39 # define FUNC fmal
40 # define DOUBLE long double
41 # define FREXP frexpl
42 # define LDEXP ldexpl
43 # define MIN_EXP LDBL_MIN_EXP
44 # define MANT_BIT LDBL_MANT_BIT
45 # define L_(literal) literal##L
46 #elif ! defined USE_FLOAT
47 # define FUNC fma
48 # define DOUBLE double
49 # define FREXP frexp
50 # define LDEXP ldexp
51 # define MIN_EXP DBL_MIN_EXP
52 # define MANT_BIT DBL_MANT_BIT
53 # define L_(literal) literal
54 #else
55 # define FUNC fmaf
56 # define DOUBLE float
57 # define FREXP frexpf
58 # define LDEXP ldexpf
59 # define MIN_EXP FLT_MIN_EXP
60 # define MANT_BIT FLT_MANT_BIT
61 # define L_(literal) literal##f
62 #endif
63
64 #undef MAX
65 #define MAX(a,b) ((a) > (b) ? (a) : (b))
66
67 #undef MIN
68 #define MIN(a,b) ((a) < (b) ? (a) : (b))
69
70
71
72 #if defined _MSC_VER && !defined __clang__
73 # pragma fenv_access (off)
74 #endif
75
76
77 #if defined __GNUC__ && defined __sparc__
78 # define VOLATILE volatile
79 #else
80 # define VOLATILE
81 #endif
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96 typedef unsigned int mp_limb_t;
97 #define GMP_LIMB_BITS 32
98 verify (sizeof (mp_limb_t) * CHAR_BIT == GMP_LIMB_BITS);
99
100 typedef unsigned long long mp_twolimb_t;
101 #define GMP_TWOLIMB_BITS 64
102 verify (sizeof (mp_twolimb_t) * CHAR_BIT == GMP_TWOLIMB_BITS);
103
104
105 #define NLIMBS1 ((MANT_BIT + GMP_LIMB_BITS - 1) / GMP_LIMB_BITS)
106
107
108 #define NLIMBS3 (3 * NLIMBS1 + 1)
109
110
111
112 static void
113 decode (DOUBLE x, mp_limb_t limbs[NLIMBS1])
114 {
115
116
117
118
119
120
121 enum { chunk_count = (MANT_BIT - 1) / 31 + 1 };
122
123 mp_limb_t *p = limbs + NLIMBS1 - 1;
124 mp_limb_t accu = 0;
125 unsigned int bits_needed = MANT_BIT - (NLIMBS1 - 1) * GMP_LIMB_BITS;
126
127
128
129 if (chunk_count > 0)
130 {
131
132 enum { chunk_bits = MIN (31, MANT_BIT - 0 * 31) };
133 mp_limb_t d;
134 x *= (mp_limb_t) 1 << chunk_bits;
135 d = (int) x;
136 x -= d;
137 if (!(x >= L_(0.0) && x < L_(1.0)))
138 abort ();
139 if (bits_needed < chunk_bits)
140 {
141
142 accu |= d >> (chunk_bits - bits_needed);
143 *p = accu;
144 if (p == limbs)
145 goto done;
146 p--;
147
148 accu = d << (GMP_LIMB_BITS - (chunk_bits - bits_needed));
149 bits_needed = GMP_LIMB_BITS - (chunk_bits - bits_needed);
150 }
151 else
152 {
153
154 accu |= d << (bits_needed - chunk_bits);
155 bits_needed -= chunk_bits;
156 if (bits_needed == 0)
157 {
158 *p = accu;
159 if (p == limbs)
160 goto done;
161 p--;
162 accu = 0;
163 bits_needed = GMP_LIMB_BITS;
164 }
165 }
166 }
167 if (chunk_count > 1)
168 {
169
170 enum { chunk_bits = MIN (31, MAX (MANT_BIT - 1 * 31, 0)) };
171 mp_limb_t d;
172 x *= (mp_limb_t) 1 << chunk_bits;
173 d = (int) x;
174 x -= d;
175 if (!(x >= L_(0.0) && x < L_(1.0)))
176 abort ();
177 if (bits_needed < chunk_bits)
178 {
179
180 accu |= d >> (chunk_bits - bits_needed);
181 *p = accu;
182 if (p == limbs)
183 goto done;
184 p--;
185
186 accu = d << (GMP_LIMB_BITS - (chunk_bits - bits_needed));
187 bits_needed = GMP_LIMB_BITS - (chunk_bits - bits_needed);
188 }
189 else
190 {
191
192 accu |= d << (bits_needed - chunk_bits);
193 bits_needed -= chunk_bits;
194 if (bits_needed == 0)
195 {
196 *p = accu;
197 if (p == limbs)
198 goto done;
199 p--;
200 accu = 0;
201 bits_needed = GMP_LIMB_BITS;
202 }
203 }
204 }
205 if (chunk_count > 2)
206 {
207
208 enum { chunk_bits = MIN (31, MAX (MANT_BIT - 2 * 31, 0)) };
209 mp_limb_t d;
210 x *= (mp_limb_t) 1 << chunk_bits;
211 d = (int) x;
212 x -= d;
213 if (!(x >= L_(0.0) && x < L_(1.0)))
214 abort ();
215 if (bits_needed < chunk_bits)
216 {
217
218 accu |= d >> (chunk_bits - bits_needed);
219 *p = accu;
220 if (p == limbs)
221 goto done;
222 p--;
223
224 accu = d << (GMP_LIMB_BITS - (chunk_bits - bits_needed));
225 bits_needed = GMP_LIMB_BITS - (chunk_bits - bits_needed);
226 }
227 else
228 {
229
230 accu |= d << (bits_needed - chunk_bits);
231 bits_needed -= chunk_bits;
232 if (bits_needed == 0)
233 {
234 *p = accu;
235 if (p == limbs)
236 goto done;
237 p--;
238 accu = 0;
239 bits_needed = GMP_LIMB_BITS;
240 }
241 }
242 }
243 if (chunk_count > 3)
244 {
245
246 enum { chunk_bits = MIN (31, MAX (MANT_BIT - 3 * 31, 0)) };
247 mp_limb_t d;
248 x *= (mp_limb_t) 1 << chunk_bits;
249 d = (int) x;
250 x -= d;
251 if (!(x >= L_(0.0) && x < L_(1.0)))
252 abort ();
253 if (bits_needed < chunk_bits)
254 {
255
256 accu |= d >> (chunk_bits - bits_needed);
257 *p = accu;
258 if (p == limbs)
259 goto done;
260 p--;
261
262 accu = d << (GMP_LIMB_BITS - (chunk_bits - bits_needed));
263 bits_needed = GMP_LIMB_BITS - (chunk_bits - bits_needed);
264 }
265 else
266 {
267
268 accu |= d << (bits_needed - chunk_bits);
269 bits_needed -= chunk_bits;
270 if (bits_needed == 0)
271 {
272 *p = accu;
273 if (p == limbs)
274 goto done;
275 p--;
276 accu = 0;
277 bits_needed = GMP_LIMB_BITS;
278 }
279 }
280 }
281 if (chunk_count > 4)
282 {
283
284
285 size_t k;
286 for (k = 4; k < chunk_count; k++)
287 {
288 size_t chunk_bits = MIN (31, MANT_BIT - k * 31);
289 mp_limb_t d;
290 x *= (mp_limb_t) 1 << chunk_bits;
291 d = (int) x;
292 x -= d;
293 if (!(x >= L_(0.0) && x < L_(1.0)))
294 abort ();
295 if (bits_needed < chunk_bits)
296 {
297
298 accu |= d >> (chunk_bits - bits_needed);
299 *p = accu;
300 if (p == limbs)
301 goto done;
302 p--;
303
304 accu = d << (GMP_LIMB_BITS - (chunk_bits - bits_needed));
305 bits_needed = GMP_LIMB_BITS - (chunk_bits - bits_needed);
306 }
307 else
308 {
309
310 accu |= d << (bits_needed - chunk_bits);
311 bits_needed -= chunk_bits;
312 if (bits_needed == 0)
313 {
314 *p = accu;
315 if (p == limbs)
316 goto done;
317 p--;
318 accu = 0;
319 bits_needed = GMP_LIMB_BITS;
320 }
321 }
322 }
323 }
324
325 abort ();
326
327 done: ;
328 #ifndef USE_LONG_DOUBLE
329
330 if (!(x == L_(0.0)))
331 abort ();
332 #endif
333 }
334
335
336 static void
337 multiply (mp_limb_t xlimbs[NLIMBS1], mp_limb_t ylimbs[NLIMBS1],
338 mp_limb_t prod_limbs[2 * NLIMBS1])
339 {
340 size_t k, i, j;
341 enum { len1 = NLIMBS1 };
342 enum { len2 = NLIMBS1 };
343
344 for (k = len2; k > 0; )
345 prod_limbs[--k] = 0;
346 for (i = 0; i < len1; i++)
347 {
348 mp_limb_t digit1 = xlimbs[i];
349 mp_twolimb_t carry = 0;
350 for (j = 0; j < len2; j++)
351 {
352 mp_limb_t digit2 = ylimbs[j];
353 carry += (mp_twolimb_t) digit1 * (mp_twolimb_t) digit2;
354 carry += prod_limbs[i + j];
355 prod_limbs[i + j] = (mp_limb_t) carry;
356 carry = carry >> GMP_LIMB_BITS;
357 }
358 prod_limbs[i + len2] = (mp_limb_t) carry;
359 }
360 }
361
362 DOUBLE
363 FUNC (DOUBLE x, DOUBLE y, DOUBLE z)
364 {
365 if (isfinite (x) && isfinite (y))
366 {
367 if (isfinite (z))
368 {
369
370 if (x == L_(0.0) || y == L_(0.0))
371 return z;
372 if (z == L_(0.0))
373 return x * y;
374
375
376 {
377 int e;
378 int sign;
379 mp_limb_t sum[NLIMBS3];
380 size_t sum_len;
381
382 {
383 int xys;
384 int zs;
385 int xye;
386 int ze;
387 mp_limb_t summand1[NLIMBS3];
388 size_t summand1_len;
389 mp_limb_t summand2[NLIMBS3];
390 size_t summand2_len;
391
392 {
393 mp_limb_t zlimbs[NLIMBS1];
394 mp_limb_t xylimbs[2 * NLIMBS1];
395
396 {
397 DOUBLE xn;
398 DOUBLE yn;
399 DOUBLE zn;
400 int xe;
401 int ye;
402 mp_limb_t xlimbs[NLIMBS1];
403 mp_limb_t ylimbs[NLIMBS1];
404
405 xys = 0;
406 xn = x;
407 if (x < 0)
408 {
409 xys = 1;
410 xn = - x;
411 }
412 yn = y;
413 if (y < 0)
414 {
415 xys = 1 - xys;
416 yn = - y;
417 }
418
419 zs = 0;
420 zn = z;
421 if (z < 0)
422 {
423 zs = 1;
424 zn = - z;
425 }
426
427
428
429 xn = FREXP (xn, &xe);
430 yn = FREXP (yn, &ye);
431 zn = FREXP (zn, &ze);
432 xye = xe + ye;
433
434
435
436 if (xye < ze - MANT_BIT)
437 {
438
439 return z;
440 }
441 if (xye - 2 * MANT_BIT > ze)
442 {
443
444
445
446
447
448
449
450
451 zn = L_(0.5);
452 ze = xye - 2 * MANT_BIT - 1;
453 }
454
455
456
457
458 decode (xn, xlimbs);
459 decode (yn, ylimbs);
460 decode (zn, zlimbs);
461
462
463 multiply (xlimbs, ylimbs, xylimbs);
464 }
465
466
467
468
469
470
471
472
473 e = MIN (xye - 2 * MANT_BIT, ze - MANT_BIT);
474 if (e == xye - 2 * MANT_BIT)
475 {
476
477 size_t i;
478 for (i = 0; i < 2 * NLIMBS1; i++)
479 summand1[i] = xylimbs[i];
480 summand1_len = 2 * NLIMBS1;
481 }
482 else
483 {
484 size_t ediff = xye - 2 * MANT_BIT - e;
485
486 size_t ldiff = ediff / GMP_LIMB_BITS;
487 size_t shift = ediff % GMP_LIMB_BITS;
488 size_t i;
489 for (i = 0; i < ldiff; i++)
490 summand1[i] = 0;
491 if (shift > 0)
492 {
493 mp_limb_t carry = 0;
494 for (i = 0; i < 2 * NLIMBS1; i++)
495 {
496 summand1[ldiff + i] = (xylimbs[i] << shift) | carry;
497 carry = xylimbs[i] >> (GMP_LIMB_BITS - shift);
498 }
499 summand1[ldiff + 2 * NLIMBS1] = carry;
500 summand1_len = ldiff + 2 * NLIMBS1 + 1;
501 }
502 else
503 {
504 for (i = 0; i < 2 * NLIMBS1; i++)
505 summand1[ldiff + i] = xylimbs[i];
506 summand1_len = ldiff + 2 * NLIMBS1;
507 }
508
509
510
511
512
513
514
515
516 if (!(summand1_len <= NLIMBS3))
517 abort ();
518 }
519 if (e == ze - MANT_BIT)
520 {
521
522 size_t i;
523 for (i = 0; i < NLIMBS1; i++)
524 summand2[i] = zlimbs[i];
525 summand2_len = NLIMBS1;
526 }
527 else
528 {
529 size_t ediff = ze - MANT_BIT - e;
530
531 size_t ldiff = ediff / GMP_LIMB_BITS;
532 size_t shift = ediff % GMP_LIMB_BITS;
533 size_t i;
534 for (i = 0; i < ldiff; i++)
535 summand2[i] = 0;
536 if (shift > 0)
537 {
538 mp_limb_t carry = 0;
539 for (i = 0; i < NLIMBS1; i++)
540 {
541 summand2[ldiff + i] = (zlimbs[i] << shift) | carry;
542 carry = zlimbs[i] >> (GMP_LIMB_BITS - shift);
543 }
544 summand2[ldiff + NLIMBS1] = carry;
545 summand2_len = ldiff + NLIMBS1 + 1;
546 }
547 else
548 {
549 for (i = 0; i < NLIMBS1; i++)
550 summand2[ldiff + i] = zlimbs[i];
551 summand2_len = ldiff + NLIMBS1;
552 }
553
554
555
556
557
558
559
560
561 if (!(summand2_len <= NLIMBS3))
562 abort ();
563 }
564 }
565
566
567 if (xys == zs)
568 {
569
570 size_t i;
571 mp_limb_t carry;
572
573 sign = xys;
574 carry = 0;
575 for (i = 0; i < MIN (summand1_len, summand2_len); i++)
576 {
577 mp_limb_t digit1 = summand1[i];
578 mp_limb_t digit2 = summand2[i];
579 sum[i] = digit1 + digit2 + carry;
580 carry = (carry
581 ? digit1 >= (mp_limb_t)-1 - digit2
582 : digit1 > (mp_limb_t)-1 - digit2);
583 }
584 if (summand1_len > summand2_len)
585 for (; i < summand1_len; i++)
586 {
587 mp_limb_t digit1 = summand1[i];
588 sum[i] = carry + digit1;
589 carry = carry && digit1 == (mp_limb_t)-1;
590 }
591 else
592 for (; i < summand2_len; i++)
593 {
594 mp_limb_t digit2 = summand2[i];
595 sum[i] = carry + digit2;
596 carry = carry && digit2 == (mp_limb_t)-1;
597 }
598 if (carry)
599 sum[i++] = carry;
600 sum_len = i;
601 }
602 else
603 {
604
605
606 while (summand1[summand1_len - 1] == 0)
607 summand1_len--;
608 while (summand2[summand2_len - 1] == 0)
609 summand2_len--;
610 if (summand1_len > summand2_len)
611 sign = xys;
612 else if (summand1_len < summand2_len)
613 sign = zs;
614 else
615 {
616 size_t i = summand1_len;
617 for (;;)
618 {
619 --i;
620 if (summand1[i] > summand2[i])
621 {
622 sign = xys;
623 break;
624 }
625 if (summand1[i] < summand2[i])
626 {
627 sign = zs;
628 break;
629 }
630 if (i == 0)
631
632 return L_(0.0);
633 }
634 }
635 if (sign == xys)
636 {
637
638 size_t i;
639 mp_limb_t carry;
640
641 carry = 0;
642 for (i = 0; i < summand2_len; i++)
643 {
644 mp_limb_t digit1 = summand1[i];
645 mp_limb_t digit2 = summand2[i];
646 sum[i] = digit1 - digit2 - carry;
647 carry = (carry ? digit1 <= digit2 : digit1 < digit2);
648 }
649 for (; i < summand1_len; i++)
650 {
651 mp_limb_t digit1 = summand1[i];
652 sum[i] = digit1 - carry;
653 carry = carry && digit1 == 0;
654 }
655 if (carry)
656 abort ();
657 sum_len = summand1_len;
658 }
659 else
660 {
661
662 size_t i;
663 mp_limb_t carry;
664
665 carry = 0;
666 for (i = 0; i < summand1_len; i++)
667 {
668 mp_limb_t digit1 = summand1[i];
669 mp_limb_t digit2 = summand2[i];
670 sum[i] = digit2 - digit1 - carry;
671 carry = (carry ? digit2 <= digit1 : digit2 < digit1);
672 }
673 for (; i < summand2_len; i++)
674 {
675 mp_limb_t digit2 = summand2[i];
676 sum[i] = digit2 - carry;
677 carry = carry && digit2 == 0;
678 }
679 if (carry)
680 abort ();
681 sum_len = summand2_len;
682 }
683 }
684 }
685
686
687
688 while (sum[sum_len - 1] == 0)
689 sum_len--;
690
691
692 {
693
694 unsigned int sum_bits =
695 integer_length (sum[sum_len - 1]) + (sum_len - 1) * GMP_LIMB_BITS;
696
697 unsigned int keep_bits;
698
699 unsigned int roundoff_bits;
700 if (e + (int) sum_bits >= MIN_EXP)
701
702
703 keep_bits = MANT_BIT;
704 else if (e + (int) sum_bits >= MIN_EXP - MANT_BIT)
705
706
707 keep_bits = e + (int) sum_bits - (MIN_EXP + MANT_BIT);
708 else
709
710 return L_(0.0);
711
712 if (sum_bits <= keep_bits)
713 {
714
715 roundoff_bits = 0;
716 keep_bits = sum_bits;
717 }
718 else
719 {
720 int round_up;
721 roundoff_bits = sum_bits - keep_bits;
722 {
723 #if HAVE_FEGETROUND && defined FE_TOWARDZERO
724
725 int rounding_mode = fegetround ();
726 if (rounding_mode == FE_TOWARDZERO)
727 round_up = 0;
728 # if defined FE_DOWNWARD
729 else if (rounding_mode == FE_DOWNWARD)
730 round_up = sign;
731 # endif
732 # if defined FE_UPWARD
733 else if (rounding_mode == FE_UPWARD)
734 round_up = !sign;
735 # endif
736 #else
737
738 int rounding_mode = FLT_ROUNDS;
739 if (rounding_mode == 0)
740 round_up = 0;
741 else if (rounding_mode == 3)
742 round_up = sign;
743 else if (rounding_mode == 2)
744 round_up = !sign;
745 #endif
746 else
747 {
748
749 round_up = 0;
750
751 if ((sum[(roundoff_bits - 1) / GMP_LIMB_BITS]
752 >> ((roundoff_bits - 1) % GMP_LIMB_BITS)) & 1)
753 {
754
755 bool halfway =
756 ((sum[(roundoff_bits - 1) / GMP_LIMB_BITS]
757 & (((mp_limb_t) 1 << ((roundoff_bits - 1) % GMP_LIMB_BITS)) - 1))
758 == 0);
759 if (halfway)
760 {
761 int i;
762 for (i = (roundoff_bits - 1) / GMP_LIMB_BITS - 1; i >= 0; i--)
763 if (sum[i] != 0)
764 {
765 halfway = false;
766 break;
767 }
768 }
769 if (halfway)
770
771 round_up = ((sum[roundoff_bits / GMP_LIMB_BITS]
772 >> (roundoff_bits % GMP_LIMB_BITS)) & 1);
773 else
774
775 round_up = 1;
776 }
777 }
778 }
779
780 {
781 size_t i = roundoff_bits / GMP_LIMB_BITS;
782 {
783 size_t j = i;
784 while (j > 0)
785 sum[--j] = 0;
786 }
787 if (round_up)
788 {
789
790 sum[i] =
791 (sum[i]
792 | (((mp_limb_t) 1 << (roundoff_bits % GMP_LIMB_BITS)) - 1))
793 + 1;
794 if (sum[i] == 0)
795 {
796
797 while (i < sum_len - 1)
798 {
799 ++i;
800 sum[i] += 1;
801 if (sum[i] != 0)
802 break;
803 }
804 }
805
806
807 if (i == sum_len - 1 && (sum[i] & (sum[i] - 1)) == 0)
808 {
809
810 if (sum[i] != 0)
811 sum_bits += 1;
812 else
813 {
814
815
816
817 sum[i] = (mp_limb_t) 1 << (GMP_LIMB_BITS - 1);
818 e += 1;
819 }
820
821 keep_bits = 1;
822 }
823 }
824 else
825 {
826
827 sum[i] &= ((mp_limb_t) -1 << (roundoff_bits % GMP_LIMB_BITS));
828 if (i == sum_len - 1 && sum[i] == 0)
829
830 return L_(0.0);
831 }
832 }
833 }
834
835
836
837
838
839
840
841
842
843 {
844
845 unsigned int chunk_count = (keep_bits - 1) / GMP_LIMB_BITS + 1;
846
847 static const DOUBLE chunk_multiplier =
848 L_(1.0) / ((DOUBLE) (1 << (GMP_LIMB_BITS / 2))
849 * (DOUBLE) (1 << ((GMP_LIMB_BITS + 1) / 2)));
850 unsigned int shift = sum_bits % GMP_LIMB_BITS;
851 DOUBLE fsum;
852 if (MANT_BIT <= GMP_LIMB_BITS)
853 {
854
855
856 if (shift == 0)
857 fsum = (DOUBLE) sum[sum_len - 1];
858 else
859 fsum = (DOUBLE)
860 ((sum[sum_len - 1] << (GMP_LIMB_BITS - shift))
861 | (sum_len >= 2 ? sum[sum_len - 2] >> shift : 0));
862 }
863 else
864 {
865 int k;
866 k = chunk_count - 1;
867 if (shift == 0)
868 {
869
870 fsum = (DOUBLE) sum[sum_len - k - 1];
871
872 while (--k >= 0)
873 {
874 fsum *= chunk_multiplier;
875 fsum += (DOUBLE) sum[sum_len - k - 1];
876 }
877 }
878 else
879 {
880
881 {
882 VOLATILE mp_limb_t chunk =
883 (sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
884 | (sum_len >= k + 2 ? sum[sum_len - k - 2] >> shift : 0);
885 fsum = (DOUBLE) chunk;
886 }
887
888 while (--k >= 0)
889 {
890 fsum *= chunk_multiplier;
891 {
892 VOLATILE mp_limb_t chunk =
893 (sum[sum_len - k - 1] << (GMP_LIMB_BITS - shift))
894 | (sum[sum_len - k - 2] >> shift);
895 fsum += (DOUBLE) chunk;
896 }
897 }
898 }
899 }
900 fsum = LDEXP (fsum, e + (int) sum_bits - GMP_LIMB_BITS);
901 return (sign ? - fsum : fsum);
902 }
903 }
904 }
905 }
906 else
907 return z;
908 }
909 else
910 return (x * y) + z;
911 }