/* Put in rp[0..n] the n+1 low limbs of {np, n} * {mp, n}. Assume 2n limbs are allocated at rp. */ void mpfr_mullow_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp, mp_size_t n) { mp_size_t k; MPFR_STAT_STATIC_ASSERT (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */ k = MPFR_LIKELY (n < MPFR_MULHIGH_TAB_SIZE) ? mulhigh_ktab[n] : 3*(n/4); MPFR_ASSERTD (k == -1 || k == 0 || (2 * k >= n && k < n)); if (k < 0) mpn_mul_basecase (rp, np, n, mp, n); else if (k == 0) mpfr_mullow_n_basecase (rp, np, mp, n); else if (n > MUL_FFT_THRESHOLD) mpn_mul_n (rp, np, mp, n); else { mp_size_t l = n - k; mpn_mul_n (rp, np, mp, k); /* fills rp[0..2k] */ mpfr_mullow_n (rp + n, np + k, mp, l); /* fills rp[n..n+2l] */ mpn_add_n (rp + k, rp + k, rp + n, l + 1); mpfr_mullow_n (rp + n, np, mp + k, l); /* fills rp[n..n+2l] */ mpn_add_n (rp + k, rp + k, rp + n, l + 1); } }
/* Put in rp[n..2n-1] an approximation of the n high limbs of {np, n} * {mp, n}. The error is less than n ulps of rp[n] (and the approximation is always less or equal to the truncated full product). Implements Algorithm ShortMul from [1]. */ void mpfr_mulhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mpfr_limb_srcptr mp, mp_size_t n) { mp_size_t k; MPFR_STAT_STATIC_ASSERT (MPFR_MULHIGH_TAB_SIZE >= 8); /* so that 3*(n/4) > n/2 */ k = MPFR_LIKELY (n < MPFR_MULHIGH_TAB_SIZE) ? mulhigh_ktab[n] : 3*(n/4); /* Algorithm ShortMul from [1] requires k >= (n+3)/2, which translates into k >= (n+4)/2 in the C language. */ MPFR_ASSERTD (k == -1 || k == 0 || (k >= (n+4)/2 && k < n)); if (k < 0) mpn_mul_basecase (rp, np, n, mp, n); /* result is exact, no error */ else if (k == 0) mpfr_mulhigh_n_basecase (rp, np, mp, n); /* basecase error < n ulps */ else if (n > MUL_FFT_THRESHOLD) mpn_mul_n (rp, np, mp, n); /* result is exact, no error */ else { mp_size_t l = n - k; mp_limb_t cy; mpn_mul_n (rp + 2 * l, np + l, mp + l, k); /* fills rp[2l..2n-1] */ mpfr_mulhigh_n (rp, np + k, mp, l); /* fills rp[l-1..2l-1] */ cy = mpn_add_n (rp + n - 1, rp + n - 1, rp + l - 1, l + 1); mpfr_mulhigh_n (rp, np, mp + k, l); /* fills rp[l-1..2l-1] */ cy += mpn_add_n (rp + n - 1, rp + n - 1, rp + l - 1, l + 1); mpn_add_1 (rp + n + l, rp + n + l, k, cy); /* propagate carry */ } }
/* Put in rp[n..2n-1] an approximation of the n high limbs of {np, n}^2. The error is less than n ulps of rp[n]. */ void mpfr_sqrhigh_n (mpfr_limb_ptr rp, mpfr_limb_srcptr np, mp_size_t n) { mp_size_t k; MPFR_STAT_STATIC_ASSERT (MPFR_SQRHIGH_TAB_SIZE > 2); /* ensures k < n */ k = MPFR_LIKELY (n < MPFR_SQRHIGH_TAB_SIZE) ? sqrhigh_ktab[n] : (n+4)/2; /* ensures that k >= (n+3)/2 */ MPFR_ASSERTD (k == -1 || k == 0 || (k >= (n+4)/2 && k < n)); if (k < 0) /* we can't use mpn_sqr_basecase here, since it requires n <= SQR_KARATSUBA_THRESHOLD, where SQR_KARATSUBA_THRESHOLD is not exported by GMP */ mpn_sqr_n (rp, np, n); else if (k == 0) mpfr_mulhigh_n_basecase (rp, np, np, n); else { mp_size_t l = n - k; mp_limb_t cy; mpn_sqr_n (rp + 2 * l, np + l, k); /* fills rp[2l..2n-1] */ mpfr_mulhigh_n (rp, np, np + k, l); /* fills rp[l-1..2l-1] */ /* {rp+n-1,l+1} += 2 * {rp+l-1,l+1} */ cy = mpn_lshift (rp + l - 1, rp + l - 1, l + 1, 1); cy += mpn_add_n (rp + n - 1, rp + n - 1, rp + l - 1, l + 1); mpn_add_1 (rp + n + l, rp + n + l, k, cy); /* propagate carry */ } }
/* * x : IN/OUT : MPFR number extracted from the file, its precision is reset to * be able to hold the number * fh : IN : file hander * Return 0 if the import was successful. */ int mpfr_fpif_import (mpfr_t x, FILE *fh) { int status; mpfr_prec_t precision; unsigned char *buffer; size_t used_size; precision = mpfr_fpif_read_precision_from_file (fh); if (precision == 0) /* precision = 0 means an error */ return -1; if (precision > MPFR_PREC_MAX) return -1; MPFR_STAT_STATIC_ASSERT (MPFR_PREC_MIN <= 8); if (precision < MPFR_PREC_MIN) precision = MPFR_PREC_MIN; mpfr_set_prec (x, precision); status = mpfr_fpif_read_exponent_from_file (x, fh); if (status != 0) return -1; if (mpfr_regular_p (x)) { used_size = (precision + 7) >> 3; /* ceil(precision/8) */ buffer = (unsigned char*) (*__gmp_allocate_func) (used_size); if (buffer == NULL) { return -1; } status = fread (buffer, used_size, 1, fh); if (status != 1) { (*__gmp_free_func) (buffer, used_size); return -1; } status = mpfr_fpif_read_limbs (x, buffer, &used_size); (*__gmp_free_func) (buffer, used_size); if (status != 0) return -1; } return 0; }
const char * mpfr_print_rnd_mode (mpfr_rnd_t rnd_mode) { /* If we forget to update this function after a new rounding mode is added, this will be detected by the following assertion. */ MPFR_STAT_STATIC_ASSERT (MPFR_RND_MAX == MPFR_RNDA + 1); switch (rnd_mode) { case MPFR_RNDD: return "MPFR_RNDD"; case MPFR_RNDU: return "MPFR_RNDU"; case MPFR_RNDN: return "MPFR_RNDN"; case MPFR_RNDZ: return "MPFR_RNDZ"; case MPFR_RNDA: return "MPFR_RNDA"; default: return (const char*) 0; } }
/* Put in {qp, n} an approximation of N={np, 2*n} divided by D={dp, n}, with the most significant limb of the quotient as return value (0 or 1). Assumes the most significant bit of D is set. Clobbers N. This implements the ShortDiv algorithm from reference [1]. */ mp_limb_t mpfr_divhigh_n (mpfr_limb_ptr qp, mpfr_limb_ptr np, mpfr_limb_ptr dp, mp_size_t n) { mp_size_t k, l; mp_limb_t qh, cy; mpfr_limb_ptr tp; MPFR_TMP_DECL(marker); MPFR_STAT_STATIC_ASSERT (MPFR_DIVHIGH_TAB_SIZE >= 15); /* so that 2*(n/3) >= (n+4)/2 */ k = MPFR_LIKELY (n < MPFR_DIVHIGH_TAB_SIZE) ? divhigh_ktab[n] : 2*(n/3); if (k == 0) #if defined(WANT_GMP_INTERNALS) && defined(HAVE___GMPN_SBPI1_DIVAPPR_Q) { mpfr_pi1_t dinv2; invert_pi1 (dinv2, dp[n - 1], dp[n - 2]); return __gmpn_sbpi1_divappr_q (qp, np, n + n, dp, n, dinv2.inv32); } #else /* use our own code for base-case short division */ return mpfr_divhigh_n_basecase (qp, np, dp, n); #endif else if (k == n)
MPFR_COLD_FUNCTION_ATTR int mpfr_erangeflag_p (void) { MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_ERANGE <= INT_MAX); return __gmpfr_flags & MPFR_FLAGS_ERANGE; }
MPFR_COLD_FUNCTION_ATTR int mpfr_inexflag_p (void) { MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_INEXACT <= INT_MAX); return __gmpfr_flags & MPFR_FLAGS_INEXACT; }
MPFR_COLD_FUNCTION_ATTR int mpfr_nanflag_p (void) { MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_NAN <= INT_MAX); return __gmpfr_flags & MPFR_FLAGS_NAN; }
MPFR_COLD_FUNCTION_ATTR int mpfr_divby0_p (void) { MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_DIVBY0 <= INT_MAX); return __gmpfr_flags & MPFR_FLAGS_DIVBY0; }
MPFR_COLD_FUNCTION_ATTR int mpfr_overflow_p (void) { MPFR_STAT_STATIC_ASSERT (MPFR_FLAGS_OVERFLOW <= INT_MAX); return __gmpfr_flags & MPFR_FLAGS_OVERFLOW; }
/* Put in X a p-bit approximation of 1/sqrt(A), where X = {x, n}/B^n, n = ceil(p/GMP_NUMB_BITS), A = 2^(1+as)*{a, an}/B^an, as is 0 or 1, an = ceil(ap/GMP_NUMB_BITS), where B = 2^GMP_NUMB_BITS. We have 1 <= A < 4 and 1/2 <= X < 1. The error in the approximate result with respect to the true value 1/sqrt(A) is bounded by 1 ulp(X), i.e., 2^{-p} since 1/2 <= X < 1. Note: x and a are left-aligned, i.e., the most significant bit of a[an-1] is set, and so is the most significant bit of the output x[n-1]. If p is not a multiple of GMP_NUMB_BITS, the extra low bits of the input A are taken into account to compute the approximation of 1/sqrt(A), but whether or not they are zero, the error between X and 1/sqrt(A) is bounded by 1 ulp(X) [in precision p]. The extra low bits of the output X (if p is not a multiple of GMP_NUMB_BITS) are set to 0. Assumptions: (1) A should be normalized, i.e., the most significant bit of a[an-1] should be 1. If as=0, we have 1 <= A < 2; if as=1, we have 2 <= A < 4. (2) p >= 12 (3) {a, an} and {x, n} should not overlap (4) GMP_NUMB_BITS >= 12 and is even Note: this routine is much more efficient when ap is small compared to p, including the case where ap <= GMP_NUMB_BITS, thus it can be used to implement an efficient mpfr_rec_sqrt_ui function. References: [1] Modern Computer Algebra, Richard Brent and Paul Zimmermann, http://www.loria.fr/~zimmerma/mca/pub226.html */ static void mpfr_mpn_rec_sqrt (mpfr_limb_ptr x, mpfr_prec_t p, mpfr_limb_srcptr a, mpfr_prec_t ap, int as) { /* the following T1 and T2 are bipartite tables giving initial approximation for the inverse square root, with 13-bit input split in 5+4+4, and 11-bit output. More precisely, if 2048 <= i < 8192, with i = a*2^8 + b*2^4 + c, we use for approximation of 2048/sqrt(i/2048) the value x = T1[16*(a-8)+b] + T2[16*(a-8)+c]. The largest error is obtained for i = 2054, where x = 2044, and 2048/sqrt(i/2048) = 2045.006576... */ static short int T1[384] = { 2040, 2033, 2025, 2017, 2009, 2002, 1994, 1987, 1980, 1972, 1965, 1958, 1951, 1944, 1938, 1931, /* a=8 */ 1925, 1918, 1912, 1905, 1899, 1892, 1886, 1880, 1874, 1867, 1861, 1855, 1849, 1844, 1838, 1832, /* a=9 */ 1827, 1821, 1815, 1810, 1804, 1799, 1793, 1788, 1783, 1777, 1772, 1767, 1762, 1757, 1752, 1747, /* a=10 */ 1742, 1737, 1733, 1728, 1723, 1718, 1713, 1709, 1704, 1699, 1695, 1690, 1686, 1681, 1677, 1673, /* a=11 */ 1669, 1664, 1660, 1656, 1652, 1647, 1643, 1639, 1635, 1631, 1627, 1623, 1619, 1615, 1611, 1607, /* a=12 */ 1603, 1600, 1596, 1592, 1588, 1585, 1581, 1577, 1574, 1570, 1566, 1563, 1559, 1556, 1552, 1549, /* a=13 */ 1545, 1542, 1538, 1535, 1532, 1528, 1525, 1522, 1518, 1515, 1512, 1509, 1505, 1502, 1499, 1496, /* a=14 */ 1493, 1490, 1487, 1484, 1481, 1478, 1475, 1472, 1469, 1466, 1463, 1460, 1457, 1454, 1451, 1449, /* a=15 */ 1446, 1443, 1440, 1438, 1435, 1432, 1429, 1427, 1424, 1421, 1419, 1416, 1413, 1411, 1408, 1405, /* a=16 */ 1403, 1400, 1398, 1395, 1393, 1390, 1388, 1385, 1383, 1380, 1378, 1375, 1373, 1371, 1368, 1366, /* a=17 */ 1363, 1360, 1358, 1356, 1353, 1351, 1349, 1346, 1344, 1342, 1340, 1337, 1335, 1333, 1331, 1329, /* a=18 */ 1327, 1325, 1323, 1321, 1319, 1316, 1314, 1312, 1310, 1308, 1306, 1304, 1302, 1300, 1298, 1296, /* a=19 */ 1294, 1292, 1290, 1288, 1286, 1284, 1282, 1280, 1278, 1276, 1274, 1272, 1270, 1268, 1266, 1265, /* a=20 */ 1263, 1261, 1259, 1257, 1255, 1253, 1251, 1250, 1248, 1246, 1244, 1242, 1241, 1239, 1237, 1235, /* a=21 */ 1234, 1232, 1230, 1229, 1227, 1225, 1223, 1222, 1220, 1218, 1217, 1215, 1213, 1212, 1210, 1208, /* a=22 */ 1206, 1204, 1203, 1201, 1199, 1198, 1196, 1195, 1193, 1191, 1190, 1188, 1187, 1185, 1184, 1182, /* a=23 */ 1181, 1180, 1178, 1177, 1175, 1174, 1172, 1171, 1169, 1168, 1166, 1165, 1163, 1162, 1160, 1159, /* a=24 */ 1157, 1156, 1154, 1153, 1151, 1150, 1149, 1147, 1146, 1144, 1143, 1142, 1140, 1139, 1137, 1136, /* a=25 */ 1135, 1133, 1132, 1131, 1129, 1128, 1127, 1125, 1124, 1123, 1121, 1120, 1119, 1117, 1116, 1115, /* a=26 */ 1114, 1113, 1111, 1110, 1109, 1108, 1106, 1105, 1104, 1103, 1101, 1100, 1099, 1098, 1096, 1095, /* a=27 */ 1093, 1092, 1091, 1090, 1089, 1087, 1086, 1085, 1084, 1083, 1081, 1080, 1079, 1078, 1077, 1076, /* a=28 */ 1075, 1073, 1072, 1071, 1070, 1069, 1068, 1067, 1065, 1064, 1063, 1062, 1061, 1060, 1059, 1058, /* a=29 */ 1057, 1056, 1055, 1054, 1052, 1051, 1050, 1049, 1048, 1047, 1046, 1045, 1044, 1043, 1042, 1041, /* a=30 */ 1040, 1039, 1038, 1037, 1036, 1035, 1034, 1033, 1032, 1031, 1030, 1029, 1028, 1027, 1026, 1025 /* a=31 */ }; static unsigned char T2[384] = { 7, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 2, 2, 1, 1, 0, /* a=8 */ 6, 5, 5, 5, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 0, 0, /* a=9 */ 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, /* a=10 */ 4, 4, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, /* a=11 */ 3, 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, /* a=12 */ 3, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* a=13 */ 3, 3, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* a=14 */ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* a=15 */ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=16 */ 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=17 */ 3, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, /* a=18 */ 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* a=19 */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, /* a=20 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* a=21 */ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=22 */ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* a=23 */ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=24 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=25 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* a=26 */ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=27 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* a=28 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, /* a=29 */ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a=30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* a=31 */ }; mp_size_t n = LIMB_SIZE(p); /* number of limbs of X */ mp_size_t an = LIMB_SIZE(ap); /* number of limbs of A */ /* A should be normalized */ MPFR_ASSERTD((a[an - 1] & MPFR_LIMB_HIGHBIT) != 0); /* We should have enough bits in one limb and GMP_NUMB_BITS should be even. Since that does not depend on MPFR, we always check this. */ MPFR_STAT_STATIC_ASSERT (GMP_NUMB_BITS >= 12 && (GMP_NUMB_BITS & 1) == 0); /* {a, an} and {x, n} should not overlap */ MPFR_ASSERTD((a + an <= x) || (x + n <= a)); MPFR_ASSERTD(p >= 11); if (MPFR_UNLIKELY(an > n)) /* we can cut the input to n limbs */ { a += an - n; an = n; } if (p == 11) /* should happen only from recursive calls */ { unsigned long i, ab, ac; mp_limb_t t; /* take the 12+as most significant bits of A */ i = a[an - 1] >> (GMP_NUMB_BITS - (12 + as)); /* if one wants faithful rounding for p=11, replace #if 0 by #if 1 */ ab = i >> 4; ac = (ab & 0x3F0) | (i & 0x0F); t = (mp_limb_t) T1[ab - 0x80] + (mp_limb_t) T2[ac - 0x80]; x[0] = t << (GMP_NUMB_BITS - p); }
/* Assumes that the exponent range has already been extended and if y is an integer, then the result is not exact in unbounded exponent range. */ int mpfr_pow_general (mpfr_ptr z, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd_mode, int y_is_integer, mpfr_save_expo_t *expo) { mpfr_t t, u, k, absx; int neg_result = 0; int k_non_zero = 0; int check_exact_case = 0; int inexact; /* Declaration of the size variable */ mpfr_prec_t Nz = MPFR_PREC(z); /* target precision */ mpfr_prec_t Nt; /* working precision */ mpfr_exp_t err; /* error */ MPFR_ZIV_DECL (ziv_loop); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg y[%Pu]=%.*Rg rnd=%d", mpfr_get_prec (x), mpfr_log_prec, x, mpfr_get_prec (y), mpfr_log_prec, y, rnd_mode), ("z[%Pu]=%.*Rg inexact=%d", mpfr_get_prec (z), mpfr_log_prec, z, inexact)); /* We put the absolute value of x in absx, pointing to the significand of x to avoid allocating memory for the significand of absx. */ MPFR_ALIAS(absx, x, /*sign=*/ 1, /*EXP=*/ MPFR_EXP(x)); /* We will compute the absolute value of the result. So, let's invert the rounding mode if the result is negative. */ if (MPFR_IS_NEG (x) && is_odd (y)) { neg_result = 1; rnd_mode = MPFR_INVERT_RND (rnd_mode); } /* compute the precision of intermediary variable */ /* the optimal number of bits : see algorithms.tex */ Nt = Nz + 5 + MPFR_INT_CEIL_LOG2 (Nz); /* initialize of intermediary variable */ mpfr_init2 (t, Nt); MPFR_ZIV_INIT (ziv_loop, Nt); for (;;) { MPFR_BLOCK_DECL (flags1); /* compute exp(y*ln|x|), using MPFR_RNDU to get an upper bound, so that we can detect underflows. */ mpfr_log (t, absx, MPFR_IS_NEG (y) ? MPFR_RNDD : MPFR_RNDU); /* ln|x| */ mpfr_mul (t, y, t, MPFR_RNDU); /* y*ln|x| */ if (k_non_zero) { MPFR_LOG_MSG (("subtract k * ln(2)\n", 0)); mpfr_const_log2 (u, MPFR_RNDD); mpfr_mul (u, u, k, MPFR_RNDD); /* Error on u = k * log(2): < k * 2^(-Nt) < 1. */ mpfr_sub (t, t, u, MPFR_RNDU); MPFR_LOG_MSG (("t = y * ln|x| - k * ln(2)\n", 0)); MPFR_LOG_VAR (t); } /* estimate of the error -- see pow function in algorithms.tex. The error on t is at most 1/2 + 3*2^(EXP(t)+1) ulps, which is <= 2^(EXP(t)+3) for EXP(t) >= -1, and <= 2 ulps for EXP(t) <= -2. Additional error if k_no_zero: treal = t * errk, with 1 - |k| * 2^(-Nt) <= exp(-|k| * 2^(-Nt)) <= errk <= 1, i.e., additional absolute error <= 2^(EXP(k)+EXP(t)-Nt). Total error <= 2^err1 + 2^err2 <= 2^(max(err1,err2)+1). */ err = MPFR_NOTZERO (t) && MPFR_GET_EXP (t) >= -1 ? MPFR_GET_EXP (t) + 3 : 1; if (k_non_zero) { if (MPFR_GET_EXP (k) > err) err = MPFR_GET_EXP (k); err++; } MPFR_BLOCK (flags1, mpfr_exp (t, t, MPFR_RNDN)); /* exp(y*ln|x|)*/ /* We need to test */ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (t) || MPFR_UNDERFLOW (flags1))) { mpfr_prec_t Ntmin; MPFR_BLOCK_DECL (flags2); MPFR_ASSERTN (!k_non_zero); MPFR_ASSERTN (!MPFR_IS_NAN (t)); /* Real underflow? */ if (MPFR_IS_ZERO (t)) { /* Underflow. We computed rndn(exp(t)), where t >= y*ln|x|. Therefore rndn(|x|^y) = 0, and we have a real underflow on |x|^y. */ inexact = mpfr_underflow (z, rnd_mode == MPFR_RNDN ? MPFR_RNDZ : rnd_mode, MPFR_SIGN_POS); if (expo != NULL) MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW); break; } /* Real overflow? */ if (MPFR_IS_INF (t)) { /* Note: we can probably use a low precision for this test. */ mpfr_log (t, absx, MPFR_IS_NEG (y) ? MPFR_RNDU : MPFR_RNDD); mpfr_mul (t, y, t, MPFR_RNDD); /* y * ln|x| */ MPFR_BLOCK (flags2, mpfr_exp (t, t, MPFR_RNDD)); /* t = lower bound on exp(y * ln|x|) */ if (MPFR_OVERFLOW (flags2)) { /* We have computed a lower bound on |x|^y, and it overflowed. Therefore we have a real overflow on |x|^y. */ inexact = mpfr_overflow (z, rnd_mode, MPFR_SIGN_POS); if (expo != NULL) MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW); break; } } k_non_zero = 1; Ntmin = sizeof(mpfr_exp_t) * CHAR_BIT; if (Ntmin > Nt) { Nt = Ntmin; mpfr_set_prec (t, Nt); } mpfr_init2 (u, Nt); mpfr_init2 (k, Ntmin); mpfr_log2 (k, absx, MPFR_RNDN); mpfr_mul (k, y, k, MPFR_RNDN); mpfr_round (k, k); MPFR_LOG_VAR (k); /* |y| < 2^Ntmin, therefore |k| < 2^Nt. */ continue; } if (MPFR_LIKELY (MPFR_CAN_ROUND (t, Nt - err, Nz, rnd_mode))) { inexact = mpfr_set (z, t, rnd_mode); break; } /* check exact power, except when y is an integer (since the exact cases for y integer have already been filtered out) */ if (check_exact_case == 0 && ! y_is_integer) { if (mpfr_pow_is_exact (z, absx, y, rnd_mode, &inexact)) break; check_exact_case = 1; } /* reactualisation of the precision */ MPFR_ZIV_NEXT (ziv_loop, Nt); mpfr_set_prec (t, Nt); if (k_non_zero) mpfr_set_prec (u, Nt); } MPFR_ZIV_FREE (ziv_loop); if (k_non_zero) { int inex2; long lk; /* The rounded result in an unbounded exponent range is z * 2^k. As * MPFR chooses underflow after rounding, the mpfr_mul_2si below will * correctly detect underflows and overflows. However, in rounding to * nearest, if z * 2^k = 2^(emin - 2), then the double rounding may * affect the result. We need to cope with that before overwriting z. * This can occur only if k < 0 (this test is necessary to avoid a * potential integer overflow). * If inexact >= 0, then the real result is <= 2^(emin - 2), so that * o(2^(emin - 2)) = +0 is correct. If inexact < 0, then the real * result is > 2^(emin - 2) and we need to round to 2^(emin - 1). */ MPFR_ASSERTN (MPFR_EXP_MAX <= LONG_MAX); lk = mpfr_get_si (k, MPFR_RNDN); /* Due to early overflow detection, |k| should not be much larger than * MPFR_EMAX_MAX, and as MPFR_EMAX_MAX <= MPFR_EXP_MAX/2 <= LONG_MAX/2, * an overflow should not be possible in mpfr_get_si (and lk is exact). * And one even has the following assertion. TODO: complete proof. */ MPFR_ASSERTD (lk > LONG_MIN && lk < LONG_MAX); /* Note: even in case of overflow (lk inexact), the code is correct. * Indeed, for the 3 occurrences of lk: * - The test lk < 0 is correct as sign(lk) = sign(k). * - In the test MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk, * if lk is inexact, then lk = LONG_MIN <= MPFR_EXP_MIN * (the minimum value of the mpfr_exp_t type), and * __gmpfr_emin - 1 - lk >= MPFR_EMIN_MIN - 1 - 2 * MPFR_EMIN_MIN * >= - MPFR_EMIN_MIN - 1 = MPFR_EMAX_MAX - 1. However, from the * choice of k, z has been chosen to be around 1, so that the * result of the test is false, as if lk were exact. * - In the mpfr_mul_2si (z, z, lk, rnd_mode), if lk is inexact, * then |lk| >= LONG_MAX >= MPFR_EXP_MAX, and as z is around 1, * mpfr_mul_2si underflows or overflows in the same way as if * lk were exact. * TODO: give a bound on |t|, then on |EXP(z)|. */ if (rnd_mode == MPFR_RNDN && inexact < 0 && lk < 0 && MPFR_GET_EXP (z) == __gmpfr_emin - 1 - lk && mpfr_powerof2_raw (z)) { /* Rounding to nearest, real result > z * 2^k = 2^(emin - 2), * underflow case: as the minimum precision is > 1, we will * obtain the correct result and exceptions by replacing z by * nextabove(z). */ MPFR_STAT_STATIC_ASSERT (MPFR_PREC_MIN > 1); mpfr_nextabove (z); } MPFR_CLEAR_FLAGS (); inex2 = mpfr_mul_2si (z, z, lk, rnd_mode); if (inex2) /* underflow or overflow */ { inexact = inex2; if (expo != NULL) MPFR_SAVE_EXPO_UPDATE_FLAGS (*expo, __gmpfr_flags); } mpfr_clears (u, k, (mpfr_ptr) 0); } mpfr_clear (t); /* update the sign of the result if x was negative */ if (neg_result) { MPFR_SET_NEG(z); inexact = -inexact; } return inexact; }