1 //   Copyright Naoki Shibata and contributors 2010 - 2020.
2 // Distributed under the Boost Software License, Version 1.0.
3 //    (See accompanying file LICENSE.txt or copy at
4 //          http://www.boost.org/LICENSE_1_0.txt)
5 
6 #include <quadmath.h>
7 #include <inttypes.h>
8 
mpfr_get_f128(mpfr_t m,mpfr_rnd_t rnd)9 static __float128 mpfr_get_f128(mpfr_t m, mpfr_rnd_t rnd) {
10   if (isnan(mpfr_get_d(m, GMP_RNDN))) return __builtin_nan("");
11 
12   mpfr_t frr, frd;
13   mpfr_inits(frr, frd, NULL);
14 
15   mpfr_exp_t e;
16   mpfr_frexp(&e, frr, m, GMP_RNDN);
17 
18   double d0 = mpfr_get_d(frr, GMP_RNDN);
19   mpfr_set_d(frd, d0, GMP_RNDN);
20   mpfr_sub(frr, frr, frd, GMP_RNDN);
21 
22   double d1 = mpfr_get_d(frr, GMP_RNDN);
23   mpfr_set_d(frd, d1, GMP_RNDN);
24   mpfr_sub(frr, frr, frd, GMP_RNDN);
25 
26   double d2 = mpfr_get_d(frr, GMP_RNDN);
27 
28   mpfr_clears(frr, frd, NULL);
29   return ldexpq((__float128)d2 + (__float128)d1 + (__float128)d0, e);
30 }
31 
mpfr_set_f128(mpfr_t frx,__float128 f,mpfr_rnd_t rnd)32 static void mpfr_set_f128(mpfr_t frx, __float128 f, mpfr_rnd_t rnd) {
33   char s[128];
34   quadmath_snprintf(s, 120, "%.50Qg", f);
35   mpfr_set_str(frx, s, 10, rnd);
36 }
37 
printf128(__float128 f)38 static void printf128(__float128 f) {
39   char s[128];
40   quadmath_snprintf(s, 120, "%.50Qg", f);
41   printf("%s", s);
42 }
43 
44 static char frstr[16][1000];
45 static int frstrcnt = 0;
46 
toBC(double d)47 static char *toBC(double d) {
48   union {
49     double d;
50     uint64_t u64;
51     int64_t i64;
52   } cnv;
53 
54   cnv.d = d;
55 
56   int64_t l = cnv.i64;
57   int e = (int)((l >> 52) & ~(-1L << 11));
58   int s = (int)(l >> 63);
59   l = d == 0 ? 0 : ((l & ~((-1L) << 52)) | (1L << 52));
60 
61   char *ptr = frstr[(frstrcnt++) & 15];
62 
63   sprintf(ptr, "%s%lld*2^%d", s != 0 ? "-" : "", (long long int)l, (e-0x3ff-52));
64   return ptr;
65 }
66 
toBCq(__float128 d)67 static char *toBCq(__float128 d) {
68   union {
69     __float128 d;
70     __uint128_t u128;
71   } cnv;
72 
73   cnv.d = d;
74 
75   __uint128_t m = cnv.u128;
76   int e = (int)((m >> 112) & ~(-1L << 15));
77   int s = (int)(m >> 127);
78   m = d == 0 ? 0 : ((m & ((((__uint128_t)1) << 112)-1)) | ((__uint128_t)1 << 112));
79 
80   uint64_t h = m / 10000000000000000000ULL;
81   uint64_t l = m % 10000000000000000000ULL;
82 
83   char *ptr = frstr[(frstrcnt++) & 15];
84 
85   sprintf(ptr, "%s%" PRIu64 "%019" PRIu64 "*2^%d", s != 0 ? "-" : "", h, l, (e-0x3fff-112));
86 
87   return ptr;
88 }
89 
xisnanq(Sleef_quad x)90 static int xisnanq(Sleef_quad x) { return x != x; }
xisinfq(Sleef_quad x)91 static int xisinfq(Sleef_quad x) { return x == (Sleef_quad)__builtin_inf() || x == -(Sleef_quad)__builtin_inf(); }
xisfiniteq(Sleef_quad x)92 static int xisfiniteq(Sleef_quad x) { return !xisnanq(x) && !isinfq(x); }
93