1 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
2 --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:40:46.838268769 +0000
3 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:40:46.870268475 +0000
6 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
7 --- mpfr-4.0.1-a/VERSION 2018-02-07 12:50:31.000000000 +0000
8 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:40:46.870268475 +0000
12 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
13 --- mpfr-4.0.1-a/src/mpfr.h 2018-02-07 12:50:31.000000000 +0000
14 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:40:46.870268475 +0000
16 #define MPFR_VERSION_MAJOR 4
17 #define MPFR_VERSION_MINOR 0
18 #define MPFR_VERSION_PATCHLEVEL 1
19 -#define MPFR_VERSION_STRING "4.0.1"
20 +#define MPFR_VERSION_STRING "4.0.1-p1"
23 MPFR_USE_FILE: Define it to make MPFR define functions dealing
24 diff -Naurd mpfr-4.0.1-a/src/sub1sp.c mpfr-4.0.1-b/src/sub1sp.c
25 --- mpfr-4.0.1-a/src/sub1sp.c 2018-01-09 12:30:58.000000000 +0000
26 +++ mpfr-4.0.1-b/src/sub1sp.c 2018-04-27 12:40:46.858268585 +0000
29 else /* cases (a), (c), (d) and (e) */
31 - ap[0] = -MPFR_LIMB_ONE;
32 /* rb=1 in case (e) and case (c) */
33 rb = d > GMP_NUMB_BITS + 1
34 || (d == GMP_NUMB_BITS + 1 && cp[0] == MPFR_LIMB_HIGHBIT);
35 /* sb = 1 in case (d) and (e) */
36 sb = d > GMP_NUMB_BITS + 1
37 || (d == GMP_NUMB_BITS + 1 && cp[0] > MPFR_LIMB_HIGHBIT);
38 + /* Warning: only set ap[0] last, otherwise in case ap=cp,
39 + the above comparisons involving cp[0] would be wrong */
40 + ap[0] = -MPFR_LIMB_ONE;
44 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
45 --- mpfr-4.0.1-a/src/version.c 2018-02-07 12:50:31.000000000 +0000
46 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:40:46.870268475 +0000
49 mpfr_get_version (void)
54 diff -Naurd mpfr-4.0.1-a/tests/tsub.c mpfr-4.0.1-b/tests/tsub.c
55 --- mpfr-4.0.1-a/tests/tsub.c 2018-01-09 12:30:58.000000000 +0000
56 +++ mpfr-4.0.1-b/tests/tsub.c 2018-04-27 12:40:46.858268585 +0000
59 #include "mpfr-test.h"
61 -#ifdef CHECK_EXTERNAL
63 test_sub (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode)
65 +#ifdef CHECK_EXTERNAL
67 int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_number_p (c);
78 -#define test_sub mpfr_sub
79 +#else /* reuse test */
82 + inex = mpfr_sub (a, b, c, rnd_mode);
84 + if (a != b && a != c && ! MPFR_IS_NAN (a))
87 + int reuse_b, reuse_c, inex_r;
89 + reuse_b = MPFR_PREC (a) == MPFR_PREC (b);
90 + reuse_c = MPFR_PREC (a) == MPFR_PREC (c);
92 + if (reuse_b || reuse_c)
93 + mpfr_init2 (t, MPFR_PREC (a));
97 + mpfr_set (t, b, MPFR_RNDN);
98 + inex_r = mpfr_sub (t, t, c, rnd_mode);
99 + if (!(mpfr_equal_p (t, a) && SAME_SIGN (inex_r, inex)))
101 + printf ("reuse of b error in b - c in %s for\n",
102 + mpfr_print_rnd_mode (rnd_mode));
107 + printf ("Expected "); mpfr_dump (a);
108 + printf (" with inex = %d\n", inex);
109 + printf ("Got "); mpfr_dump (t);
110 + printf (" with inex = %d\n", inex_r);
117 + mpfr_set (t, c, MPFR_RNDN);
118 + inex_r = mpfr_sub (t, b, t, rnd_mode);
119 + if (!(mpfr_equal_p (t, a) && SAME_SIGN (inex_r, inex)))
121 + printf ("reuse of c error in b - c in %s for\n",
122 + mpfr_print_rnd_mode (rnd_mode));
127 + printf ("Expected "); mpfr_dump (a);
128 + printf (" with inex = %d\n", inex);
129 + printf ("Got "); mpfr_dump (t);
130 + printf (" with inex = %d\n", inex_r);
135 + if (reuse_b || reuse_c)
145 @@ -940,6 +1000,80 @@
149 +/* Fails with r12281: "reuse of c error in b - c in MPFR_RNDN". */
153 + mpfr_t x, y, z1, z2;
154 + int r, p, d, i, inex1, inex2;
156 + for (p = 3; p <= 3 + 4 * GMP_NUMB_BITS; p++)
158 + mpfr_inits2 (p, x, y, z1, z2, (mpfr_ptr) 0);
159 + for (d = p; d <= p+4; d++)
161 + mpfr_set_ui (x, 1, MPFR_RNDN);
162 + mpfr_set_ui_2exp (y, 1, -d, MPFR_RNDN);
163 + for (i = 0; i < 3; i++)
165 + RND_LOOP_NO_RNDF (r)
167 + mpfr_set (z1, x, MPFR_RNDN);
170 + mpfr_nextbelow (z1);
173 + else if (r == MPFR_RNDD || r == MPFR_RNDZ ||
174 + (r == MPFR_RNDN && i > 1))
176 + mpfr_nextbelow (z1);
182 + else if (r == MPFR_RNDD || r == MPFR_RNDZ ||
183 + (r == MPFR_RNDN && d == p+1 && i > 0))
185 + mpfr_nextbelow (z1);
190 + inex2 = test_sub (z2, x, y, (mpfr_rnd_t) r);
191 + if (!(mpfr_equal_p (z1, z2) && SAME_SIGN (inex1, inex2)))
193 + printf ("Error in bug20180217 with "
194 + "p=%d, d=%d, i=%d, %s\n", p, d, i,
195 + mpfr_print_rnd_mode ((mpfr_rnd_t) r));
200 + printf ("Expected "); mpfr_dump (z1);
201 + printf (" with inex = %d\n", inex1);
202 + printf ("Got "); mpfr_dump (z2);
203 + printf (" with inex = %d\n", inex2);
208 + mpfr_nextabove (y);
213 + mpfr_nextbelow (y);
214 + mpfr_mul_ui (y, y, 25, MPFR_RNDD);
215 + mpfr_div_2ui (y, y, 4, MPFR_RNDN);
219 + mpfr_clears (x, y, z1, z2, (mpfr_ptr) 0);
223 #define TEST_FUNCTION test_sub
225 #define RAND_FUNCTION(x) mpfr_random2(x, MPFR_LIMB_SIZE (x), randlimb () % 100, RANDS)
228 check_max_almosteven ();
231 for (p=2; p<200; p++)
234 diff -Naurd mpfr-4.0.1-a/tests/tsub1sp.c mpfr-4.0.1-b/tests/tsub1sp.c
235 --- mpfr-4.0.1-a/tests/tsub1sp.c 2018-01-09 12:30:58.000000000 +0000
236 +++ mpfr-4.0.1-b/tests/tsub1sp.c 2018-04-27 12:40:46.858268585 +0000
244 + mpfr_t a, b, c, d, u;
247 + /* coverage test in mpfr_sub1sp: case d=1, limb > MPFR_LIMB_HIGHBIT, RNDF
249 + mpfr_init2 (a, 3 * GMP_NUMB_BITS);
250 + mpfr_init2 (b, 3 * GMP_NUMB_BITS);
251 + mpfr_init2 (c, 3 * GMP_NUMB_BITS);
252 + mpfr_init2 (d, 3 * GMP_NUMB_BITS);
253 + mpfr_init2 (u, 3 * GMP_NUMB_BITS);
254 + mpfr_set_ui (b, 1, MPFR_RNDN);
255 + mpfr_nextbelow (b); /* b = 1 - 2^(-p) */
256 + mpfr_set_prec (c, GMP_NUMB_BITS);
257 + mpfr_set_ui_2exp (c, 1, -1, MPFR_RNDN);
258 + mpfr_nextbelow (c);
259 + mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) */
260 + mpfr_prec_round (c, 3 * GMP_NUMB_BITS, MPFR_RNDN);
261 + mpfr_nextbelow (c); /* c = 1/2 - 2*2^(-GMP_NUMB_BITS-1) - 2^(-p-1) */
263 + mpfr_sub (a, b, c, MPFR_RNDF);
264 + mpfr_sub (d, b, c, MPFR_RNDD);
265 + mpfr_sub (u, b, c, MPFR_RNDU);
266 + /* check a = d or u */
267 + MPFR_ASSERTN(mpfr_equal_p (a, d) || mpfr_equal_p (a, u));
269 + /* coverage test in mpfr_sub1sp: case d=p, RNDN, sb = 0, significand of b
270 + is even but b<>2^e, (case 1e) */
271 + mpfr_set_prec (a, 3 * GMP_NUMB_BITS);
272 + mpfr_set_prec (b, 3 * GMP_NUMB_BITS);
273 + mpfr_set_prec (c, 3 * GMP_NUMB_BITS);
274 + mpfr_set_ui (b, 1, MPFR_RNDN);
275 + mpfr_nextabove (b);
276 + mpfr_nextabove (b);
277 + mpfr_set_ui_2exp (c, 1, -3 * GMP_NUMB_BITS, MPFR_RNDN);
278 + inex = mpfr_sub (a, b, c, MPFR_RNDN);
279 + MPFR_ASSERTN(inex > 0);
280 + MPFR_ASSERTN(mpfr_equal_p (a, b));
289 +/* bug in mpfr_sub1sp1n, made generic */
291 +bug20180217 (mpfr_prec_t pmax)
297 + for (p = MPFR_PREC_MIN; p <= pmax; p++)
302 + mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
303 + mpfr_set_ui_2exp (c, 1, -p-1, MPFR_RNDN); /* c = 2^(-p-1) */
304 + /* a - b = 1 - 2^(-p-1) and should be rounded to 1 (case 2f of
306 + inex = mpfr_sub (a, b, c, MPFR_RNDN);
307 + MPFR_ASSERTN(inex > 0);
308 + MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
309 + /* check also when a=b */
310 + mpfr_set_ui (a, 1, MPFR_RNDN);
311 + inex = mpfr_sub (a, a, c, MPFR_RNDN);
312 + MPFR_ASSERTN(inex > 0);
313 + MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
315 + mpfr_set_ui (b, 1, MPFR_RNDN); /* b = 1 */
316 + mpfr_set_ui_2exp (a, 1, -p-1, MPFR_RNDN);
317 + inex = mpfr_sub (a, b, a, MPFR_RNDN);
318 + MPFR_ASSERTN(inex > 0);
319 + MPFR_ASSERTN(mpfr_cmp_ui (a, 1) == 0);
333 + bug20180217 (1024);
335 compare_sub_sub1sp ();
338 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
339 --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:45:53.139452673 +0000
340 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:45:53.171452379 +0000
343 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
344 --- mpfr-4.0.1-a/VERSION 2018-04-27 12:40:46.870268475 +0000
345 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:45:53.171452379 +0000
349 diff -Naurd mpfr-4.0.1-a/src/fma.c mpfr-4.0.1-b/src/fma.c
350 --- mpfr-4.0.1-a/src/fma.c 2018-01-09 12:30:58.000000000 +0000
351 +++ mpfr-4.0.1-b/src/fma.c 2018-04-27 12:45:53.159452489 +0000
352 @@ -225,194 +225,73 @@
354 if (MPFR_IS_INF (u)) /* overflow */
356 + int sign_u = MPFR_SIGN (u);
358 MPFR_LOG_MSG (("Overflow on x*y\n", 0));
359 + MPFR_GROUP_CLEAR (group); /* we no longer need u */
361 /* Let's eliminate the obvious case where x*y and z have the
362 same sign. No possible cancellation -> real overflow.
363 Also, we know that |z| < 2^emax. If E(x) + E(y) >= emax+3,
364 - then |x*y| >= 2^(emax+1), and |x*y + z| >= 2^emax. This case
365 + then |x*y| >= 2^(emax+1), and |x*y + z| > 2^emax. This case
366 is also an overflow. */
367 - if (MPFR_SIGN (u) == MPFR_SIGN (z) || e >= __gmpfr_emax + 3)
368 + if (sign_u == MPFR_SIGN (z) || e >= __gmpfr_emax + 3)
370 - MPFR_GROUP_CLEAR (group);
371 MPFR_SAVE_EXPO_FREE (expo);
372 - return mpfr_overflow (s, rnd_mode, MPFR_SIGN (z));
373 + return mpfr_overflow (s, rnd_mode, sign_u);
376 - /* E(x) + E(y) <= emax+2, therefore |x*y| < 2^(emax+2), and
377 - (x/4)*y does not overflow (let's recall that the result
378 - is exact with an unbounded exponent range). It does not
379 - underflow either, because x*y overflows and the exponent
380 - range is large enough. */
381 - inexact = mpfr_div_2ui (u, x, 2, MPFR_RNDN);
382 - MPFR_ASSERTN (inexact == 0);
383 - inexact = mpfr_mul (u, u, y, MPFR_RNDN);
384 - MPFR_ASSERTN (inexact == 0);
386 - /* Now, we need to add z/4... But it may underflow! */
390 - MPFR_BLOCK_DECL (flags);
392 - if (MPFR_GET_EXP (u) > MPFR_GET_EXP (z) &&
393 - MPFR_GET_EXP (u) - MPFR_GET_EXP (z) > MPFR_PREC (u))
395 - /* |z| < ulp(u)/2, therefore one can use z instead of z/4. */
400 - mpfr_init2 (zo4, MPFR_PREC (z));
401 - if (mpfr_div_2ui (zo4, z, 2, MPFR_RNDZ))
403 - /* The division by 4 underflowed! */
404 - MPFR_ASSERTN (0); /* TODO... */
409 - /* Let's recall that u = x*y/4 and zz = z/4 (or z if the
410 - following addition would give the same result). */
411 - MPFR_BLOCK (flags, inexact = mpfr_add (s, u, zz, rnd_mode));
412 - /* u and zz have different signs, so that an overflow
413 - is not possible. But an underflow is theoretically
415 - if (MPFR_UNDERFLOW (flags))
417 - MPFR_ASSERTN (zz != z);
418 - MPFR_ASSERTN (0); /* TODO... */
419 - mpfr_clears (zo4, u, (mpfr_ptr) 0);
427 - MPFR_GROUP_CLEAR (group);
428 - MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
429 - inex2 = mpfr_mul_2ui (s, s, 2, rnd_mode);
430 - if (inex2) /* overflow */
433 - MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
439 - else /* underflow: one has |xy| < 2^(emin-1). */
440 + else /* underflow: one has |x*y| < 2^(emin-1). */
442 - unsigned long scale = 0;
445 - mpfr_exp_t diffexp;
449 MPFR_LOG_MSG (("Underflow on x*y\n", 0));
451 - /* Let's scale z so that ulp(z) > 2^emin and ulp(s) > 2^emin
452 - (the + 1 on MPFR_PREC (s) is necessary because the exponent
453 - of the result can be EXP(z) - 1). */
454 - diffexp = MPFR_GET_EXP (z) - __gmpfr_emin;
455 - pzs = MAX (MPFR_PREC (z), MPFR_PREC (s) + 1);
456 - MPFR_LOG_MSG (("diffexp=%" MPFR_EXP_FSPEC "d pzs=%Pd\n",
458 - if (diffexp <= pzs)
460 - mpfr_uexp_t uscale;
462 - MPFR_BLOCK_DECL (flags);
464 - uscale = (mpfr_uexp_t) pzs - diffexp + 1;
465 - MPFR_ASSERTN (uscale > 0);
466 - MPFR_ASSERTN (uscale <= ULONG_MAX);
468 - mpfr_init2 (scaled_z, MPFR_PREC (z));
469 - inexact = mpfr_mul_2ui (scaled_z, z, scale, MPFR_RNDN);
470 - MPFR_ASSERTN (inexact == 0); /* TODO: overflow case */
472 - /* Now we need to recompute u = xy * 2^scale. */
474 - if (MPFR_GET_EXP (x) < MPFR_GET_EXP (y))
476 - mpfr_init2 (scaled_v, precx);
477 - mpfr_mul_2ui (scaled_v, x, scale, MPFR_RNDN);
478 - mpfr_mul (u, scaled_v, y, MPFR_RNDN);
482 - mpfr_init2 (scaled_v, precy);
483 - mpfr_mul_2ui (scaled_v, y, scale, MPFR_RNDN);
484 - mpfr_mul (u, x, scaled_v, MPFR_RNDN);
486 - mpfr_clear (scaled_v);
487 - MPFR_ASSERTN (! MPFR_OVERFLOW (flags));
488 - xy_underflows = MPFR_UNDERFLOW (flags);
496 - MPFR_LOG_MSG (("scale=%lu xy_underflows=%d\n",
497 - scale, xy_underflows));
500 + /* Easy cases: when 2^(emin-1) <= 1/2 * min(ulp(z),ulp(s)),
501 + one can replace x*y by sign(x*y) * 2^(emin-1). Note that
502 + this is even true in case of equality for MPFR_RNDN thanks
503 + to the even-rounding rule.
504 + The + 1 on MPFR_PREC (s) is necessary because the exponent
505 + of the result can be EXP(z) - 1. */
506 + if (MPFR_GET_EXP (z) - __gmpfr_emin >=
507 + MAX (MPFR_PREC (z), MPFR_PREC (s) + 1))
509 - /* Let's replace xy by sign(xy) * 2^(emin-1). */
510 MPFR_PREC (u) = MPFR_PREC_MIN;
511 mpfr_setmin (u, __gmpfr_emin);
512 MPFR_SET_SIGN (u, MPFR_MULT_SIGN (MPFR_SIGN (x),
514 + mpfr_clear_flags ();
519 - MPFR_BLOCK_DECL (flags);
520 + MPFR_GROUP_CLEAR (group); /* we no longer need u */
523 - MPFR_BLOCK (flags, inexact = mpfr_add (s, u, new_z, rnd_mode));
524 - MPFR_LOG_MSG (("inexact=%d\n", inexact));
525 - MPFR_GROUP_CLEAR (group);
529 + /* Let's use UBF to resolve the overflow/underflow issues. */
534 + MPFR_TMP_DECL(marker);
536 - mpfr_clear (scaled_z);
537 - /* Here an overflow is theoretically possible, in which case
538 - the result may be wrong, hence the assert. An underflow
539 - is not possible, but let's check that anyway. */
540 - MPFR_ASSERTN (! MPFR_OVERFLOW (flags)); /* TODO... */
541 - MPFR_ASSERTN (! MPFR_UNDERFLOW (flags)); /* not possible */
542 - if (rnd_mode == MPFR_RNDN &&
543 - MPFR_GET_EXP (s) == __gmpfr_emin - 1 + scale &&
544 - mpfr_powerof2_raw (s))
546 - MPFR_LOG_MSG (("Double rounding\n", 0));
547 - rnd_mode = (MPFR_IS_NEG (s) ? inexact <= 0 : inexact >= 0)
548 - ? MPFR_RNDZ : MPFR_RNDA;
550 - inex2 = mpfr_div_2ui (s, s, scale, rnd_mode);
551 - MPFR_LOG_MSG (("inex2=%d\n", inex2));
552 - if (inex2) /* underflow */
556 + MPFR_LOG_MSG (("Use UBF\n", 0));
558 - /* FIXME/TODO: I'm not sure that the following is correct.
559 - Check for possible spurious exceptions due to intermediate
561 - MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
564 + MPFR_TMP_MARK (marker);
565 + un = MPFR_LIMB_SIZE (x) + MPFR_LIMB_SIZE (y);
566 + MPFR_TMP_INIT (up, uu, (mpfr_prec_t) un * GMP_NUMB_BITS, un);
567 + mpfr_ubf_mul_exact (uu, x, y);
568 + mpfr_clear_flags ();
569 + inexact = mpfr_add (s, (mpfr_srcptr) uu, z, rnd_mode);
570 + MPFR_UBF_CLEAR_EXP (uu);
571 + MPFR_TMP_FREE (marker);
577 + inexact = mpfr_add (s, u, z, rnd_mode);
578 + MPFR_GROUP_CLEAR (group);
581 - inexact = mpfr_add (s, u, z, rnd_mode);
582 - MPFR_GROUP_CLEAR (group);
583 MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
585 MPFR_SAVE_EXPO_FREE (expo);
586 return mpfr_check_range (s, inexact, rnd_mode);
588 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
589 --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:40:46.870268475 +0000
590 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:45:53.171452379 +0000
592 #define MPFR_VERSION_MAJOR 4
593 #define MPFR_VERSION_MINOR 0
594 #define MPFR_VERSION_PATCHLEVEL 1
595 -#define MPFR_VERSION_STRING "4.0.1-p1"
596 +#define MPFR_VERSION_STRING "4.0.1-p2"
599 MPFR_USE_FILE: Define it to make MPFR define functions dealing
600 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
601 --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:40:46.870268475 +0000
602 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:45:53.171452379 +0000
605 mpfr_get_version (void)
610 diff -Naurd mpfr-4.0.1-a/tests/tfma.c mpfr-4.0.1-b/tests/tfma.c
611 --- mpfr-4.0.1-a/tests/tfma.c 2018-01-09 12:30:58.000000000 +0000
612 +++ mpfr-4.0.1-b/tests/tfma.c 2018-04-27 12:45:53.163452452 +0000
613 @@ -196,6 +196,238 @@
617 +test_overflow3 (void)
622 + mpfr_flags_t ex_flags = MPFR_FLAGS_OVERFLOW | MPFR_FLAGS_INEXACT, flags;
626 + mpfr_inits2 (p, x, y, z, (mpfr_ptr) 0);
627 + for (i = 0; i < 2; i++)
629 + mpfr_init2 (r, 2 * p + i);
630 + mpfr_set_ui_2exp (x, 1, mpfr_get_emax () - 1, MPFR_RNDN);
631 + mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */
632 + for (j = 1; j <= 2; j++)
633 + for (k = 0; k <= 1; k++)
635 + mpfr_set_si_2exp (z, -1, mpfr_get_emax () - mpfr_get_prec (r) - j,
638 + mpfr_nextabove (z);
639 + for (neg = 0; neg <= 3; neg++)
641 + mpfr_clear_flags ();
642 + /* (The following applies for neg = 0 or 2, all the signs
643 + need to be reversed for neg = 1 or 3.)
644 + We have x*y = 2^emax and
645 + z = - 2^(emax-2p-i-j) * (1-k*2^(-p)), thus
646 + x*y+z = 2^emax - 2^(emax-2p-i-j) + k*2^(emax-3p-i-j)
647 + should overflow. Indeed it is >= the midpoint of
648 + 2^emax - 2^(emax-2p-i) and 2^emax, the midpoint
649 + being obtained for j = 1 and k = 0. */
650 + inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
651 + flags = __gmpfr_flags;
652 + if (! mpfr_inf_p (r) || flags != ex_flags ||
654 + (inex <= 0 || MPFR_IS_NEG (r)) :
655 + (inex >= 0 || MPFR_IS_POS (r))))
657 + printf ("Error in test_overflow3 for "
658 + "i=%d j=%d k=%d neg=%u\n", i, j, k, neg);
659 + printf ("Expected %c@Inf@\n with inex %c 0 and flags:",
660 + (neg & 1) == 0 ? '+' : '-',
661 + (neg & 1) == 0 ? '>' : '<');
662 + flags_out (ex_flags);
665 + printf (" with inex = %d and flags:", inex);
669 + if (neg == 0 || neg == 2)
670 + mpfr_neg (x, x, MPFR_RNDN);
671 + if (neg == 1 || neg == 3)
672 + mpfr_neg (y, y, MPFR_RNDN);
673 + mpfr_neg (z, z, MPFR_RNDN);
678 + mpfr_clears (x, y, z, (mpfr_ptr) 0);
682 +test_overflow4 (void)
684 + mpfr_t x, y, z, r1, r2;
685 + mpfr_exp_t emax, e;
687 + mpfr_flags_t flags1, flags2;
693 + emax = mpfr_get_emax ();
695 + mpfr_init2 (y, MPFR_PREC_MIN);
696 + mpfr_set_ui (y, 2, MPFR_RNDN); /* y = 2 */
700 + for (px = 17; px < 256; px *= 2)
702 + mpfr_init2 (x, px);
703 + mpfr_inits2 (px - 8, r1, r2, (mpfr_ptr) 0);
704 + for (ei = 0; ei <= 1; ei++)
707 + mpfr_set_ui_2exp (x, 1, e - 1, MPFR_RNDN);
708 + mpfr_nextabove (x); /* x = 2^(e - 1) + 2^(e - px) */
709 + /* x*y = 2^e + 2^(e - px + 1), which internally overflows
711 + for (i = -4; i <= 4; i++)
712 + for (j = 2; j <= 3; j++)
714 + mpfr_set_si_2exp (z, -j, e - px + i, MPFR_RNDN);
715 + /* If |z| <= 2^(e - px + 1), then x*y + z >= 2^e and
716 + RZ(x*y + z) = 2^e with an unbounded exponent range.
717 + If |z| > 2^(e - px + 1), then RZ(x*y + z) is the
718 + predecessor of 2^e (since |z| < ulp(r)/2); this
719 + occurs when i > 0 and when i = 0 and j > 2 */
720 + mpfr_set_ui_2exp (r1, 1, e - 1, MPFR_RNDN);
721 + below = i > 0 || (i == 0 && j > 2);
723 + mpfr_nextbelow (r1);
724 + mpfr_clear_flags ();
725 + inex1 = mpfr_mul_2ui (r1, r1, 1, MPFR_RNDZ);
726 + if (below || e < emax)
728 + inex1 = i == 0 && j == 2 ? 0 : -1;
729 + flags1 = inex1 ? MPFR_FLAGS_INEXACT : 0;
733 + MPFR_ASSERTN (inex1 < 0);
734 + flags1 = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
735 + MPFR_ASSERTN (flags1 == __gmpfr_flags);
737 + for (neg = 0; neg <= 3; neg++)
739 + mpfr_clear_flags ();
740 + inex2 = mpfr_fma (r2, x, y, z, MPFR_RNDZ);
741 + flags2 = __gmpfr_flags;
742 + if (! (mpfr_equal_p (r1, r2) &&
743 + SAME_SIGN (inex1, inex2) &&
746 + printf ("Error in test_overflow4 for "
747 + "px=%d ei=%d i=%d j=%d neg=%u\n",
748 + (int) px, ei, i, j, neg);
749 + printf ("Expected ");
751 + printf ("with inex = %d and flags:", inex1);
752 + flags_out (flags1);
755 + printf ("with inex = %d and flags:", inex2);
756 + flags_out (flags2);
759 + if (neg == 0 || neg == 2)
760 + mpfr_neg (x, x, MPFR_RNDN);
761 + if (neg == 1 || neg == 3)
762 + mpfr_neg (y, y, MPFR_RNDN);
763 + mpfr_neg (z, z, MPFR_RNDN);
764 + mpfr_neg (r1, r1, MPFR_RNDN);
769 + mpfr_clears (x, r1, r2, (mpfr_ptr) 0);
772 + mpfr_clears (y, z, (mpfr_ptr) 0);
776 +test_overflow5 (void)
778 + mpfr_t x, y, z, r1, r2;
782 + unsigned int neg, negr;
784 + emax = mpfr_get_emax ();
786 + mpfr_init2 (x, 123);
787 + mpfr_init2 (y, 45);
788 + mpfr_init2 (z, 67);
789 + mpfr_inits2 (89, r1, r2, (mpfr_ptr) 0);
791 + mpfr_set_ui_2exp (x, 1, emax - 1, MPFR_RNDN);
793 + for (i = 3; i <= 17; i++)
795 + mpfr_set_ui (y, i, MPFR_RNDN);
796 + mpfr_set_ui_2exp (z, 1, emax - 1, MPFR_RNDN);
797 + for (neg = 0; neg < 8; neg++)
799 + mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
800 + mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
801 + mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
803 + /* |x*y + z| = (i +/- 1) * 2^(emax - 1) >= 2^emax (overflow)
804 + and x*y + z has the same sign as x*y. */
805 + negr = (neg ^ (neg >> 1)) & 1;
809 + mpfr_set_inf (r1, 1);
810 + if (MPFR_IS_LIKE_RNDZ ((mpfr_rnd_t) rnd, negr))
812 + mpfr_nextbelow (r1);
820 + mpfr_neg (r1, r1, MPFR_RNDN);
824 + mpfr_clear_flags ();
825 + inex2 = mpfr_fma (r2, x, y, z, (mpfr_rnd_t) rnd);
826 + MPFR_ASSERTN (__gmpfr_flags ==
827 + (MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW));
829 + if (! (mpfr_equal_p (r1, r2) && SAME_SIGN (inex1, inex2)))
831 + printf ("Error in test_overflow5 for i=%d neg=%u %s\n",
832 + i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
833 + printf ("Expected ");
835 + printf ("with inex = %d\n", inex1);
838 + printf ("with inex = %d\n", inex2);
845 + mpfr_clears (x, y, z, r1, r2, (mpfr_ptr) 0);
849 test_underflow1 (void)
852 @@ -281,59 +513,128 @@
854 test_underflow2 (void)
857 - int b, i, inex, same, err = 0;
858 + mpfr_t x, y, z, r1, r2;
859 + int e, b, i, prec = 32, pz, inex;
862 - mpfr_inits2 (32, x, y, z, r, (mpfr_ptr) 0);
863 + mpfr_init2 (x, MPFR_PREC_MIN);
864 + mpfr_inits2 (prec, y, z, r1, r2, (mpfr_ptr) 0);
866 - mpfr_set_si_2exp (z, 1, mpfr_get_emin (), MPFR_RNDN); /* z = 2^emin */
867 - mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN); /* x = 2^emin */
868 + mpfr_set_si_2exp (x, 1, mpfr_get_emin () - 1, MPFR_RNDN);
869 + /* x = 2^(emin-1) */
871 - for (b = 0; b <= 1; b++)
872 + for (e = -1; e <= prec + 2; e++)
874 - for (i = 15; i <= 17; i++)
875 + mpfr_set (z, x, MPFR_RNDN);
876 + /* z = x = 2^(emin+e) */
877 + for (b = 0; b <= 1; b++)
879 - mpfr_set_si_2exp (y, i, -4 - MPFR_PREC (z), MPFR_RNDN);
885 - mpfr_clear_flags ();
886 - inex = mpfr_fma (r, x, y, z, MPFR_RNDN);
887 -#define STRTU2 "Error in test_underflow2 (b = %d, i = %d)\n "
888 - if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
890 - printf (STRTU2 "flags = %u instead of %u\n", b, i,
891 - (unsigned int) __gmpfr_flags,
892 - (unsigned int) MPFR_FLAGS_INEXACT);
895 - same = i == 15 || (i == 16 && b == 0);
896 - if (same ? (inex >= 0) : (inex <= 0))
898 - printf (STRTU2 "incorrect ternary value (%d instead of %c 0)\n",
899 - b, i, inex, same ? '<' : '>');
902 - mpfr_set (y, z, MPFR_RNDN);
904 - mpfr_nextabove (y);
905 - if (! mpfr_equal_p (r, y))
906 + for (pz = prec - 4 * (b == 0); pz <= prec + 4; pz++)
908 - printf (STRTU2 "expected ", b, i);
915 - mpfr_nextabove (z);
917 + inex = mpfr_prec_round (z, pz, MPFR_RNDZ);
918 + MPFR_ASSERTN (inex == 0);
919 + for (i = 15; i <= 17; i++)
921 + mpfr_flags_t flags1, flags2;
926 - mpfr_clears (x, y, z, r, (mpfr_ptr) 0);
927 + mpfr_set_si_2exp (y, i, -4 - prec, MPFR_RNDN);
930 + * z = 1.000...00b with b = 0 or 1
931 + * xy = 01111 (i = 15)
932 + * or 10000 (i = 16)
933 + * or 10001 (i = 17)
935 + * x, y, and z will be modified to test the different sign
936 + * combinations. In the case b = 0 (i.e. |z| is a power of
937 + * 2) and x*y has a different sign from z, then y will be
938 + * divided by 2, so that i = 16 corresponds to a midpoint.
941 + for (neg = 0; neg < 8; neg++)
943 + int xyneg, prev_binade;
945 + mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
946 + mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
947 + mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
949 + xyneg = (neg ^ (neg >> 1)) & 1; /* true iff x*y < 0 */
951 + /* If a change of binade occurs by adding x*y to z
952 + exactly, then take into account the fact that the
953 + midpoint has a different exponent. */
954 + prev_binade = b == 0 && (xyneg ^ MPFR_IS_NEG (z));
956 + mpfr_div_2ui (y, y, 1, MPFR_RNDN);
958 + mpfr_set (r1, z, MPFR_RNDN);
959 + flags1 = MPFR_FLAGS_INEXACT;
961 + if (e == -1 && i == 17 && b == 0 &&
962 + (xyneg ^ (neg >> 2)) != 0)
964 + /* Special underflow case. */
965 + flags1 |= MPFR_FLAGS_UNDERFLOW;
966 + inex1 = xyneg ? 1 : -1;
968 + else if (i == 15 || (i == 16 && b == 0))
970 + /* round toward z */
971 + inex1 = xyneg ? 1 : -1;
975 + /* round away from z, with x*y < 0 */
976 + mpfr_nextbelow (r1);
981 + /* round away from z, with x*y > 0 */
982 + mpfr_nextabove (r1);
986 + mpfr_clear_flags ();
987 + inex2 = mpfr_fma (r2, x, y, z, MPFR_RNDN);
988 + flags2 = __gmpfr_flags;
990 + if (! (mpfr_equal_p (r1, r2) &&
991 + SAME_SIGN (inex1, inex2) &&
994 + printf ("Error in test_underflow2 for "
995 + "e=%d b=%d pz=%d i=%d neg=%u\n",
997 + printf ("Expected ");
999 + printf ("with inex = %d and flags:", inex1);
1000 + flags_out (flags1);
1003 + printf ("with inex = %d and flags:", inex2);
1004 + flags_out (flags2);
1010 + mpfr_mul_2ui (y, y, 1, MPFR_RNDN);
1015 + inex = mpfr_prec_round (z, prec, MPFR_RNDZ);
1016 + MPFR_ASSERTN (inex == 0);
1018 + mpfr_nextabove (z);
1020 + mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
1023 + mpfr_clears (x, y, z, r1, r2, (mpfr_ptr) 0);
1027 @@ -397,6 +698,185 @@
1028 mpfr_clears (x, y, z, t1, t2, (mpfr_ptr) 0);
1031 +/* Test s = x*y + z with PREC(z) > PREC(s) + 1, x*y underflows, where
1032 + z + x*y and z + sign(x*y) * 2^(emin-1) do not give the same result.
1035 + z = 2^emin * (2^PREC(s) + k - 2^(-1))
1036 + with k = 3 for MPFR_RNDN and k = 2 for the directed rounding modes.
1037 + Also test the opposite versions with neg != 0.
1040 +test_underflow4 (void)
1042 + mpfr_t x, y, z, s1, s2;
1043 + mpfr_prec_t ps = 32;
1046 + mpfr_inits2 (MPFR_PREC_MIN, x, y, (mpfr_ptr) 0);
1047 + mpfr_inits2 (ps, s1, s2, (mpfr_ptr) 0);
1048 + mpfr_init2 (z, ps + 2);
1050 + inex = mpfr_set_si_2exp (x, 1, mpfr_get_emin (), MPFR_RNDN);
1051 + MPFR_ASSERTN (inex == 0);
1052 + inex = mpfr_set_si_2exp (y, 1, -8, MPFR_RNDN);
1053 + MPFR_ASSERTN (inex == 0);
1055 + RND_LOOP_NO_RNDF (rnd)
1057 + mpfr_flags_t flags1, flags2;
1061 + inex = mpfr_set_si_2exp (z, 1 << 1, ps, MPFR_RNDN);
1062 + MPFR_ASSERTN (inex == 0);
1063 + inex = mpfr_sub_ui (z, z, 1, MPFR_RNDN);
1064 + MPFR_ASSERTN (inex == 0);
1065 + inex = mpfr_div_2ui (z, z, 1, MPFR_RNDN);
1066 + MPFR_ASSERTN (inex == 0);
1067 + inex = mpfr_add_ui (z, z, rnd == MPFR_RNDN ? 3 : 2, MPFR_RNDN);
1068 + MPFR_ASSERTN (inex == 0);
1069 + inex = mpfr_mul (z, z, x, MPFR_RNDN);
1070 + MPFR_ASSERTN (inex == 0);
1072 + for (neg = 0; neg <= 3; neg++)
1074 + inex1 = mpfr_set (s1, z, (mpfr_rnd_t) rnd);
1075 + flags1 = MPFR_FLAGS_INEXACT;
1077 + mpfr_clear_flags ();
1078 + inex2 = mpfr_fma (s2, x, y, z, (mpfr_rnd_t) rnd);
1079 + flags2 = __gmpfr_flags;
1081 + if (! (mpfr_equal_p (s1, s2) &&
1082 + SAME_SIGN (inex1, inex2) &&
1083 + flags1 == flags2))
1085 + printf ("Error in test_underflow4 for neg=%u %s\n",
1086 + neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
1087 + printf ("Expected ");
1089 + printf (" with inex ~ %d, flags =", inex1);
1090 + flags_out (flags1);
1093 + printf (" with inex ~ %d, flags =", inex2);
1094 + flags_out (flags2);
1098 + if (neg == 0 || neg == 2)
1099 + mpfr_neg (x, x, MPFR_RNDN);
1100 + if (neg == 1 || neg == 3)
1101 + mpfr_neg (y, y, MPFR_RNDN);
1102 + mpfr_neg (z, z, MPFR_RNDN);
1106 + mpfr_clears (x, y, z, s1, s2, (mpfr_ptr) 0);
1109 +/* Test s = x*y + z on:
1112 + z = +/- 2^(emin + PREC(s)) and MPFR numbers close to this value.
1113 + with PREC(z) from PREC(s) - 2 to PREC(s) + 8.
1116 +test_underflow5 (void)
1118 + mpfr_t w, x, y, z, s1, s2, t;
1120 + mpfr_prec_t ps = 32;
1121 + int inex, i, j, rnd;
1124 + mpfr_inits2 (MPFR_PREC_MIN, w, x, y, (mpfr_ptr) 0);
1125 + mpfr_inits2 (ps, s1, s2, (mpfr_ptr) 0);
1126 + mpfr_init2 (t, ps + 9);
1128 + emin = mpfr_get_emin ();
1130 + inex = mpfr_set_si_2exp (w, 1, emin, MPFR_RNDN); /* w = 2^emin */
1131 + MPFR_ASSERTN (inex == 0);
1132 + inex = mpfr_set_si (x, 1, MPFR_RNDN);
1133 + MPFR_ASSERTN (inex == 0);
1134 + inex = mpfr_set_si_2exp (y, 1, -3, MPFR_RNDN);
1135 + MPFR_ASSERTN (inex == 0);
1137 + for (i = -2; i <= 8; i++)
1139 + mpfr_init2 (z, ps + i);
1140 + inex = mpfr_set_si_2exp (z, 1, ps, MPFR_RNDN);
1141 + MPFR_ASSERTN (inex == 0);
1143 + for (j = 1; j <= 32; j++)
1144 + mpfr_nextbelow (z);
1146 + for (j = -32; j <= 32; j++)
1148 + for (neg = 0; neg < 8; neg++)
1150 + mpfr_setsign (x, x, neg & 1, MPFR_RNDN);
1151 + mpfr_setsign (y, y, neg & 2, MPFR_RNDN);
1152 + mpfr_setsign (z, z, neg & 4, MPFR_RNDN);
1154 + inex = mpfr_fma (t, x, y, z, MPFR_RNDN);
1155 + MPFR_ASSERTN (inex == 0);
1157 + inex = mpfr_mul (x, x, w, MPFR_RNDN);
1158 + MPFR_ASSERTN (inex == 0);
1159 + inex = mpfr_mul (z, z, w, MPFR_RNDN);
1160 + MPFR_ASSERTN (inex == 0);
1162 + RND_LOOP_NO_RNDF (rnd)
1164 + mpfr_flags_t flags1, flags2;
1167 + mpfr_clear_flags ();
1168 + inex1 = mpfr_mul (s1, w, t, (mpfr_rnd_t) rnd);
1169 + flags1 = __gmpfr_flags;
1171 + mpfr_clear_flags ();
1172 + inex2 = mpfr_fma (s2, x, y, z, (mpfr_rnd_t) rnd);
1173 + flags2 = __gmpfr_flags;
1175 + if (! (mpfr_equal_p (s1, s2) &&
1176 + SAME_SIGN (inex1, inex2) &&
1177 + flags1 == flags2))
1179 + printf ("Error in test_underflow5 on "
1180 + "i=%d j=%d neg=%u %s\n", i, j, neg,
1181 + mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
1182 + printf ("Expected ");
1184 + printf (" with inex ~ %d, flags =", inex1);
1185 + flags_out (flags1);
1188 + printf (" with inex ~ %d, flags =", inex2);
1189 + flags_out (flags2);
1194 + inex = mpfr_div (x, x, w, MPFR_RNDN);
1195 + MPFR_ASSERTN (inex == 0);
1196 + inex = mpfr_div (z, z, w, MPFR_RNDN);
1197 + MPFR_ASSERTN (inex == 0);
1200 + MPFR_SET_POS (z); /* restore the value before the loop on neg */
1201 + mpfr_nextabove (z);
1207 + mpfr_clears (w, x, y, s1, s2, t, (mpfr_ptr) 0);
1213 @@ -533,6 +1013,7 @@
1216 mpfr_exp_t emin, emax;
1219 tests_start_mpfr ();
1221 @@ -823,21 +1304,39 @@
1225 - test_overflow1 ();
1226 - test_overflow2 ();
1227 - test_underflow1 ();
1228 - test_underflow2 ();
1229 - test_underflow3 (1);
1230 + for (i = 0; i <= 2; i++)
1234 + /* corresponds to the generic code + mpfr_check_range */
1240 + set_emin (MPFR_EMIN_MIN);
1241 + set_emax (MPFR_EMAX_MAX);
1245 + MPFR_ASSERTN (i == 2);
1246 + if (emin == MPFR_EMIN_MIN && emax == MPFR_EMAX_MAX)
1252 - set_emin (MPFR_EMIN_MIN);
1253 - set_emax (MPFR_EMAX_MAX);
1254 - test_overflow1 ();
1255 - test_overflow2 ();
1256 - test_underflow1 ();
1257 - test_underflow2 ();
1258 - test_underflow3 (2);
1261 + test_overflow1 ();
1262 + test_overflow2 ();
1263 + test_overflow3 ();
1264 + test_overflow4 ();
1265 + test_overflow5 ();
1266 + test_underflow1 ();
1267 + test_underflow2 ();
1268 + test_underflow3 (i);
1269 + test_underflow4 ();
1270 + test_underflow5 ();
1275 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
1276 --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:47:54.194308761 +0000
1277 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:47:54.230308407 +0000
1280 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
1281 --- mpfr-4.0.1-a/VERSION 2018-04-27 12:45:53.171452379 +0000
1282 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:47:54.226308446 +0000
1286 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
1287 --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:45:53.171452379 +0000
1288 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:47:54.226308446 +0000
1290 #define MPFR_VERSION_MAJOR 4
1291 #define MPFR_VERSION_MINOR 0
1292 #define MPFR_VERSION_PATCHLEVEL 1
1293 -#define MPFR_VERSION_STRING "4.0.1-p2"
1294 +#define MPFR_VERSION_STRING "4.0.1-p3"
1297 MPFR_USE_FILE: Define it to make MPFR define functions dealing
1298 diff -Naurd mpfr-4.0.1-a/src/sqr.c mpfr-4.0.1-b/src/sqr.c
1299 --- mpfr-4.0.1-a/src/sqr.c 2018-01-09 12:30:58.000000000 +0000
1300 +++ mpfr-4.0.1-b/src/sqr.c 2018-04-27 12:47:54.218308525 +0000
1301 @@ -161,15 +161,18 @@
1302 if (MPFR_UNLIKELY(ax < __gmpfr_emin))
1304 /* As seen in mpfr_mul_1, we cannot have a0 = 111...111 here if there
1305 - was not exponent decrease (ax--) above.
1306 - In the case of an exponent decrease, it is not possible for
1307 - GMP_NUMB_BITS=32 since the largest b0 such that b0^2 < 2^(2*32-1)
1308 - is b0=3037000499, but its square has only 30 leading ones.
1309 - For GMP_NUMB_BITS=64 it is possible: the largest b0 is
1310 - 13043817825332782212, and its square has 64 leading ones. */
1311 - if ((ax == __gmpfr_emin - 1) && (ap[0] == ~MPFR_LIMB_HIGHBIT) &&
1312 - ((rnd_mode == MPFR_RNDN && rb) ||
1313 - (MPFR_IS_LIKE_RNDA(rnd_mode, MPFR_IS_NEG (a)) && (rb | sb))))
1314 + was not an exponent decrease (ax--) above.
1315 + In the case of an exponent decrease:
1316 + - For GMP_NUMB_BITS=32, a0 = 111...111 is not possible since the
1317 + largest b0 such that b0^2 < 2^(2*32-1) is b0=3037000499, but
1318 + its square has only 30 leading ones.
1319 + - For GMP_NUMB_BITS=64, a0 = 111...111 is possible: the largest b0
1320 + is 13043817825332782212, and its square has 64 leading ones; but
1321 + since the next bit is rb=0, for RNDN, we always have an underflow.
1322 + For the test below, note that a is positive.
1324 + if (ax == __gmpfr_emin - 1 && ap[0] == MPFR_LIMB_MAX &&
1325 + MPFR_IS_LIKE_RNDA (rnd_mode, 0))
1326 goto rounding; /* no underflow */
1327 /* For RNDN, mpfr_underflow always rounds away, thus for |a| <= 2^(emin-2)
1328 we have to change to RNDZ. This corresponds to:
1329 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
1330 --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:45:53.171452379 +0000
1331 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:47:54.226308446 +0000
1334 mpfr_get_version (void)
1336 - return "4.0.1-p2";
1337 + return "4.0.1-p3";
1339 diff -Naurd mpfr-4.0.1-a/tests/tsqr.c mpfr-4.0.1-b/tests/tsqr.c
1340 --- mpfr-4.0.1-a/tests/tsqr.c 2018-01-09 12:30:58.000000000 +0000
1341 +++ mpfr-4.0.1-b/tests/tsqr.c 2018-04-27 12:47:54.218308525 +0000
1342 @@ -188,6 +188,156 @@
1347 +coverage (mpfr_prec_t pmax)
1351 + for (p = MPFR_PREC_MIN; p <= pmax; p++)
1357 + mpfr_init2 (a, p);
1358 + mpfr_init2 (b, p);
1359 + mpfr_init2 (c, p);
1361 + /* exercise carry in most significant bits of a, with overflow */
1362 + mpfr_set_ui_2exp (b, 1, mpfr_get_emax (), MPFR_RNDZ);
1363 + mpfr_sqrt (b, b, MPFR_RNDU);
1364 + mpfr_div_2exp (c, b, 1, MPFR_RNDN);
1365 + mpfr_sqr (c, c, MPFR_RNDN);
1366 + mpfr_clear_flags ();
1367 + inex = mpfr_sqr (a, b, MPFR_RNDN);
1368 + /* if EXP(c) > emax-2, there is overflow */
1369 + if (mpfr_get_exp (c) > mpfr_get_emax () - 2)
1371 + MPFR_ASSERTN(inex > 0);
1372 + MPFR_ASSERTN(mpfr_inf_p (a) && mpfr_sgn (a) > 0);
1373 + MPFR_ASSERTN(mpfr_overflow_p ());
1375 + else /* no overflow */
1377 + /* 2^p-1 is a square only for p=1 */
1378 + MPFR_ASSERTN((p == 1 && inex == 0) || (p > 1 && inex < 0));
1379 + MPFR_ASSERTN(!mpfr_overflow_p ());
1380 + mpfr_set_ui_2exp (c, 1, mpfr_get_emax (), MPFR_RNDZ);
1381 + MPFR_ASSERTN(mpfr_equal_p (a, c));
1384 + /* same as above, with RNDU */
1385 + mpfr_set_ui_2exp (b, 1, mpfr_get_emax (), MPFR_RNDZ);
1386 + mpfr_sqrt (b, b, MPFR_RNDU);
1387 + mpfr_div_2exp (c, b, 1, MPFR_RNDN);
1388 + mpfr_sqr (c, c, MPFR_RNDU);
1389 + mpfr_clear_flags ();
1390 + inex = mpfr_sqr (a, b, MPFR_RNDU);
1391 + /* if EXP(c) > emax-2, there is overflow */
1392 + if (mpfr_get_exp (c) > mpfr_get_emax () - 2)
1394 + MPFR_ASSERTN(inex > 0);
1395 + MPFR_ASSERTN(mpfr_inf_p (a) && mpfr_sgn (a) > 0);
1396 + MPFR_ASSERTN(mpfr_overflow_p ());
1398 + else /* no overflow */
1400 + /* 2^p-1 is a square only for p=1 */
1401 + MPFR_ASSERTN((p == 1 && inex == 0) || (p > 1 && inex < 0));
1402 + MPFR_ASSERTN(!mpfr_overflow_p ());
1403 + mpfr_set_ui_2exp (c, 1, mpfr_get_emax (), MPFR_RNDZ);
1404 + MPFR_ASSERTN(mpfr_equal_p (a, c));
1407 + /* exercise trivial overflow */
1408 + mpfr_set_ui_2exp (b, 1, mpfr_get_emax (), MPFR_RNDZ);
1409 + mpfr_sqrt (b, b, MPFR_RNDU);
1410 + mpfr_mul_2exp (b, b, 1, MPFR_RNDN);
1411 + mpfr_clear_flags ();
1412 + inex = mpfr_sqr (a, b, MPFR_RNDN);
1413 + MPFR_ASSERTN(inex > 0);
1414 + MPFR_ASSERTN(mpfr_inf_p (a) && mpfr_sgn (a) > 0);
1415 + MPFR_ASSERTN(mpfr_overflow_p ());
1417 + /* exercise trivial underflow */
1418 + mpfr_set_ui_2exp (b, 1, mpfr_get_emin () - 1, MPFR_RNDZ);
1419 + mpfr_sqrt (b, b, MPFR_RNDU);
1420 + mpfr_div_2exp (b, b, 1, MPFR_RNDN);
1421 + mpfr_clear_flags ();
1422 + inex = mpfr_sqr (a, b, MPFR_RNDN);
1423 + MPFR_ASSERTN(inex < 0);
1424 + MPFR_ASSERTN(mpfr_zero_p (a) && mpfr_signbit (a) == 0);
1425 + MPFR_ASSERTN(mpfr_underflow_p ());
1427 + /* exercise square between 0.5*2^emin and its predecessor (emin even) */
1428 + emin = mpfr_get_emin ();
1429 + mpfr_set_emin (emin + (emin & 1)); /* now emin is even */
1430 + mpfr_set_ui_2exp (b, 1, mpfr_get_emin () - 1, MPFR_RNDN);
1431 + inex = mpfr_sqrt (b, b, MPFR_RNDZ);
1432 + MPFR_ASSERTN(inex != 0); /* sqrt(2) is not exact */
1433 + mpfr_mul_2exp (c, b, 1, MPFR_RNDN);
1434 + mpfr_sqr (c, c, MPFR_RNDN);
1435 + mpfr_clear_flags ();
1436 + inex = mpfr_sqr (a, b, MPFR_RNDN);
1437 + if (mpfr_get_exp (c) < mpfr_get_emin () + 2) /* underflow */
1439 + /* if c > 0.5*2^(emin+1), we should round to 0.5*2^emin */
1440 + if (mpfr_cmp_ui_2exp (c, 1, mpfr_get_emin ()) > 0)
1442 + MPFR_ASSERTN(inex > 0);
1443 + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, mpfr_get_emin () - 1) == 0);
1444 + MPFR_ASSERTN(mpfr_underflow_p ());
1446 + else /* we should round to 0 */
1448 + MPFR_ASSERTN(inex < 0);
1449 + MPFR_ASSERTN(mpfr_zero_p (a) && mpfr_signbit (a) == 0);
1450 + MPFR_ASSERTN(mpfr_underflow_p ());
1455 + MPFR_ASSERTN(inex > 0);
1456 + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, mpfr_get_emin () - 1) == 0);
1457 + MPFR_ASSERTN(!mpfr_underflow_p ());
1459 + mpfr_set_emin (emin);
1461 + /* exercise exact square root 2^(emin-2) for emin even */
1462 + emin = mpfr_get_emin ();
1463 + mpfr_set_emin (emin + (emin & 1)); /* now emin is even */
1464 + mpfr_set_ui_2exp (b, 1, (mpfr_get_emin () - 2) / 2, MPFR_RNDN);
1465 + inex = mpfr_sqr (a, b, MPFR_RNDN);
1466 + MPFR_ASSERTN(inex < 0);
1467 + MPFR_ASSERTN(mpfr_zero_p (a) && mpfr_signbit (a) == 0);
1468 + MPFR_ASSERTN(mpfr_underflow_p ());
1469 + mpfr_set_emin (emin);
1471 + /* same as above, for RNDU */
1472 + emin = mpfr_get_emin ();
1473 + mpfr_set_emin (emin + (emin & 1)); /* now emin is even */
1474 + mpfr_set_ui_2exp (b, 1, mpfr_get_emin () - 1, MPFR_RNDN);
1475 + inex = mpfr_sqrt (b, b, MPFR_RNDZ);
1476 + MPFR_ASSERTN(inex != 0); /* sqrt(2) is not exact */
1477 + mpfr_mul_2exp (c, b, 1, MPFR_RNDN);
1478 + mpfr_sqr (c, c, MPFR_RNDU);
1479 + mpfr_clear_flags ();
1480 + inex = mpfr_sqr (a, b, MPFR_RNDU);
1481 + MPFR_ASSERTN(inex > 0);
1482 + MPFR_ASSERTN(mpfr_cmp_ui_2exp (a, 1, mpfr_get_emin () - 1) == 0);
1483 + /* we have underflow if c < 2^(emin+1) */
1484 + if (mpfr_cmp_ui_2exp (c, 1, mpfr_get_emin () + 1) < 0)
1485 + MPFR_ASSERTN(mpfr_underflow_p ());
1487 + MPFR_ASSERTN(!mpfr_underflow_p ());
1488 + mpfr_set_emin (emin);
1501 tests_start_mpfr ();
1507 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
1508 --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:50:10.592974822 +0000
1509 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:50:10.624974512 +0000
1512 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
1513 --- mpfr-4.0.1-a/VERSION 2018-04-27 12:47:54.226308446 +0000
1514 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:50:10.624974512 +0000
1518 diff -Naurd mpfr-4.0.1-a/doc/mpfr.info mpfr-4.0.1-b/doc/mpfr.info
1519 --- mpfr-4.0.1-a/doc/mpfr.info 2018-02-07 12:58:03.000000000 +0000
1520 +++ mpfr-4.0.1-b/doc/mpfr.info 2018-04-27 12:50:17.128911341 +0000
1521 @@ -1321,10 +1321,9 @@
1522 size_t N, mpfr_t OP, mpfr_rnd_t RND)
1523 Convert OP to a string of digits in base B, with rounding in the
1524 direction RND, where N is either zero (see below) or the number of
1525 - significant digits output in the string; in the latter case, N must
1526 - be greater or equal to 2. The base may vary from 2 to 62;
1527 - otherwise the function does nothing and immediately returns a null
1529 + significant digits output in the string. The base may vary from 2
1530 + to 62; otherwise the function does nothing and immediately returns
1533 If the input is NaN, then the returned string is ‘@NaN@’ and the
1534 NaN flag is set. If the input is +Inf (resp. −Inf), then the
1535 @@ -4471,21 +4470,21 @@
1536 * mpfr_expm1: Special Functions. (line 40)
1537 * mpfr_fac_ui: Special Functions. (line 136)
1538 * mpfr_fits_intmax_p: Conversion Functions.
1541 * mpfr_fits_sint_p: Conversion Functions.
1544 * mpfr_fits_slong_p: Conversion Functions.
1547 * mpfr_fits_sshort_p: Conversion Functions.
1550 * mpfr_fits_uintmax_p: Conversion Functions.
1553 * mpfr_fits_uint_p: Conversion Functions.
1556 * mpfr_fits_ulong_p: Conversion Functions.
1559 * mpfr_fits_ushort_p: Conversion Functions.
1562 * mpfr_flags_clear: Exception Related Functions.
1564 * mpfr_flags_restore: Exception Related Functions.
1565 @@ -4520,7 +4519,7 @@
1566 * mpfr_free_cache2: Special Functions. (line 295)
1567 * mpfr_free_pool: Special Functions. (line 309)
1568 * mpfr_free_str: Conversion Functions.
1571 * mpfr_frexp: Conversion Functions.
1573 * mpfr_gamma: Special Functions. (line 155)
1574 @@ -4928,30 +4927,30 @@
1575 Node: Assignment Functions
\x7f47553
1576 Node: Combined Initialization and Assignment Functions
\x7f57499
1577 Node: Conversion Functions
\x7f58800
1578 -Node: Basic Arithmetic Functions
\x7f69381
1579 -Node: Comparison Functions
\x7f80277
1580 -Node: Special Functions
\x7f83765
1581 -Node: Input and Output Functions
\x7f101974
1582 -Node: Formatted Output Functions
\x7f106751
1583 -Node: Integer and Remainder Related Functions
\x7f116956
1584 -Node: Rounding-Related Functions
\x7f124484
1585 -Node: Miscellaneous Functions
\x7f131001
1586 -Node: Exception Related Functions
\x7f141493
1587 -Node: Compatibility with MPF
\x7f151733
1588 -Node: Custom Interface
\x7f154679
1589 -Node: Internals
\x7f159310
1590 -Node: API Compatibility
\x7f160854
1591 -Node: Type and Macro Changes
\x7f162802
1592 -Node: Added Functions
\x7f165985
1593 -Node: Changed Functions
\x7f170499
1594 -Node: Removed Functions
\x7f177095
1595 -Node: Other Changes
\x7f177825
1596 -Node: MPFR and the IEEE 754 Standard
\x7f179526
1597 -Node: Contributors
\x7f182143
1598 -Node: References
\x7f185200
1599 -Node: GNU Free Documentation License
\x7f187084
1600 -Node: Concept Index
\x7f209677
1601 -Node: Function and Type Index
\x7f216049
1602 +Node: Basic Arithmetic Functions
\x7f69323
1603 +Node: Comparison Functions
\x7f80219
1604 +Node: Special Functions
\x7f83707
1605 +Node: Input and Output Functions
\x7f101916
1606 +Node: Formatted Output Functions
\x7f106693
1607 +Node: Integer and Remainder Related Functions
\x7f116898
1608 +Node: Rounding-Related Functions
\x7f124426
1609 +Node: Miscellaneous Functions
\x7f130943
1610 +Node: Exception Related Functions
\x7f141435
1611 +Node: Compatibility with MPF
\x7f151675
1612 +Node: Custom Interface
\x7f154621
1613 +Node: Internals
\x7f159252
1614 +Node: API Compatibility
\x7f160796
1615 +Node: Type and Macro Changes
\x7f162744
1616 +Node: Added Functions
\x7f165927
1617 +Node: Changed Functions
\x7f170441
1618 +Node: Removed Functions
\x7f177037
1619 +Node: Other Changes
\x7f177767
1620 +Node: MPFR and the IEEE 754 Standard
\x7f179468
1621 +Node: Contributors
\x7f182085
1622 +Node: References
\x7f185142
1623 +Node: GNU Free Documentation License
\x7f187026
1624 +Node: Concept Index
\x7f209619
1625 +Node: Function and Type Index
\x7f215991
1629 diff -Naurd mpfr-4.0.1-a/doc/mpfr.texi mpfr-4.0.1-b/doc/mpfr.texi
1630 --- mpfr-4.0.1-a/doc/mpfr.texi 2018-02-07 12:50:31.000000000 +0000
1631 +++ mpfr-4.0.1-b/doc/mpfr.texi 2018-04-27 12:50:10.612974628 +0000
1632 @@ -1655,8 +1655,8 @@
1633 @deftypefun {char *} mpfr_get_str (char *@var{str}, mpfr_exp_t *@var{expptr}, int @var{b}, size_t @var{n}, mpfr_t @var{op}, mpfr_rnd_t @var{rnd})
1634 Convert @var{op} to a string of digits in base @var{b}, with rounding in
1635 the direction @var{rnd}, where @var{n} is either zero (see below) or the
1636 -number of significant digits output in the string; in the latter case,
1637 -@var{n} must be greater or equal to 2. The base may vary from 2 to 62;
1638 +number of significant digits output in the string.
1639 +The base may vary from 2 to 62;
1640 otherwise the function does nothing and immediately returns a null pointer.
1642 If the input is NaN, then the returned string is @samp{@@NaN@@} and the
1643 @@ -1699,8 +1699,7 @@
1644 but in some very rare cases, it might be @math{m+1}
1645 (the smallest case for bases up to 62 is when @var{p} equals 186564318007
1646 for bases 7 and 49).
1647 -@c In the source src/get_str.c, this is due to the approximate mpfr_ceil_mul,
1648 -@c but also m = 1 is changed to 2.
1649 +@c In the source src/get_str.c, this is due to the approximate mpfr_ceil_mul.
1651 If @var{str} is a null pointer, space for the significand is allocated using
1652 the allocation function (@pxref{Memory Handling}) and a pointer to the string
1653 diff -Naurd mpfr-4.0.1-a/src/get_str.c mpfr-4.0.1-b/src/get_str.c
1654 --- mpfr-4.0.1-a/src/get_str.c 2018-01-09 12:30:58.000000000 +0000
1655 +++ mpfr-4.0.1-b/src/get_str.c 2018-04-27 12:50:10.612974628 +0000
1656 @@ -2325,15 +2325,12 @@
1659 mpfr_ceil_mul (IS_POW2(b) ? MPFR_PREC(x) - 1 : MPFR_PREC(x), b, 1);
1664 MPFR_LOG_MSG (("m=%zu\n", m));
1666 - /* The code below for non-power-of-two bases works for m=1;
1667 - this is important for the internal use of mpfr_get_str. */
1668 - MPFR_ASSERTN (m >= 2 || (!IS_POW2(b) && m >= 1));
1669 + /* The code below works for m=1, both for power-of-two and non-power-of-two
1670 + bases; this is important for the internal use of mpfr_get_str. */
1672 /* x is a floating-point number */
1674 @@ -2376,6 +2373,8 @@
1676 /* the first digit will contain only r bits */
1677 prec = (m - 1) * pow2 + r; /* total number of bits */
1678 + /* if m=1 then 1 <= prec <= pow2, and since prec=1 is now valid in MPFR,
1679 + the power-of-two code also works for m=1 */
1680 n = MPFR_PREC2LIMBS (prec);
1682 MPFR_TMP_MARK (marker);
1683 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
1684 --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:47:54.226308446 +0000
1685 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:50:10.620974551 +0000
1687 #define MPFR_VERSION_MAJOR 4
1688 #define MPFR_VERSION_MINOR 0
1689 #define MPFR_VERSION_PATCHLEVEL 1
1690 -#define MPFR_VERSION_STRING "4.0.1-p3"
1691 +#define MPFR_VERSION_STRING "4.0.1-p4"
1694 MPFR_USE_FILE: Define it to make MPFR define functions dealing
1695 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
1696 --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:47:54.226308446 +0000
1697 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:50:10.624974512 +0000
1700 mpfr_get_version (void)
1702 - return "4.0.1-p3";
1703 + return "4.0.1-p4";
1705 diff -Naurd mpfr-4.0.1-a/tests/tget_str.c mpfr-4.0.1-b/tests/tget_str.c
1706 --- mpfr-4.0.1-a/tests/tget_str.c 2018-01-09 12:30:58.000000000 +0000
1707 +++ mpfr-4.0.1-b/tests/tget_str.c 2018-04-27 12:50:10.612974628 +0000
1708 @@ -1267,6 +1267,41 @@
1721 + mpfr_init2 (x, 128);
1723 + /* exercise corner case in mpfr_get_str_aux: exact case (e < 0), where r
1724 + rounds to a power of 2, and f is a multiple of GMP_NUMB_BITS */
1725 + mpfr_set_ui_2exp (x, 1, 64, MPFR_RNDU);
1726 + mpfr_nextbelow (x);
1727 + /* x = 2^64 - 2^(-64) */
1728 + mpfr_get_str (s, &e, b, m, x, MPFR_RNDU);
1729 + /* s is the base-3 string for 6148914691236517206 (in base 10) */
1730 + MPFR_ASSERTN(strcmp (s, "1111222002212212010121102012021021021200") == 0);
1731 + MPFR_ASSERTN(e == 41);
1733 + /* exercise corner case in mpfr_get_str: input is m=0, then it is changed
1735 + mpfr_set_prec (x, 1);
1736 + mpfr_set_ui (x, 1, MPFR_RNDN);
1737 + mpfr_get_str (s, &e, 2, 0, x, MPFR_RNDN);
1738 + MPFR_ASSERTN(strcmp (s, "1") == 0);
1739 + MPFR_ASSERTN(e == 1);
1740 + mpfr_get_str (s, &e, 2, 1, x, MPFR_RNDN);
1741 + MPFR_ASSERTN(strcmp (s, "1") == 0);
1742 + MPFR_ASSERTN(e == 1);
1748 main (int argc, char *argv[])
1750 @@ -1281,6 +1316,7 @@
1752 tests_start_mpfr ();
1757 check_special (2, 2);
1758 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
1759 --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:52:13.875783093 +0000
1760 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:52:13.911782747 +0000
1763 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
1764 --- mpfr-4.0.1-a/VERSION 2018-04-27 12:50:10.624974512 +0000
1765 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:52:13.911782747 +0000
1769 diff -Naurd mpfr-4.0.1-a/src/gmp_op.c mpfr-4.0.1-b/src/gmp_op.c
1770 --- mpfr-4.0.1-a/src/gmp_op.c 2018-01-09 12:30:58.000000000 +0000
1771 +++ mpfr-4.0.1-b/src/gmp_op.c 2018-04-27 12:52:13.899782862 +0000
1772 @@ -452,11 +452,15 @@
1774 MPFR_SAVE_EXPO_DECL (expo);
1776 - if (MPFR_UNLIKELY (mpq_denref (q) == 0))
1777 + if (MPFR_UNLIKELY (mpz_sgn (mpq_denref (q)) == 0))
1779 /* q is an infinity or NaN */
1780 - mpfr_init2 (t, 2);
1781 + mpfr_flags_t old_flags;
1783 + mpfr_init2 (t, MPFR_PREC_MIN);
1784 + old_flags = __gmpfr_flags;
1785 mpfr_set_q (t, q, MPFR_RNDN);
1786 + __gmpfr_flags = old_flags;
1787 res = mpfr_cmp (x, t);
1790 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
1791 --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:50:10.620974551 +0000
1792 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:52:13.907782785 +0000
1794 #define MPFR_VERSION_MAJOR 4
1795 #define MPFR_VERSION_MINOR 0
1796 #define MPFR_VERSION_PATCHLEVEL 1
1797 -#define MPFR_VERSION_STRING "4.0.1-p4"
1798 +#define MPFR_VERSION_STRING "4.0.1-p5"
1801 MPFR_USE_FILE: Define it to make MPFR define functions dealing
1802 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
1803 --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:50:10.624974512 +0000
1804 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:52:13.911782747 +0000
1807 mpfr_get_version (void)
1809 - return "4.0.1-p4";
1810 + return "4.0.1-p5";
1812 diff -Naurd mpfr-4.0.1-a/tests/tgmpop.c mpfr-4.0.1-b/tests/tgmpop.c
1813 --- mpfr-4.0.1-a/tests/tgmpop.c 2018-01-09 12:30:58.000000000 +0000
1814 +++ mpfr-4.0.1-b/tests/tgmpop.c 2018-04-27 12:52:13.899782862 +0000
1815 @@ -307,16 +307,39 @@
1816 mpfr_init2 (z, MPFR_PREC_MIN);
1819 - /* check the erange flag when x is NaN */
1820 + /* Check the flags when x is NaN: the erange flags must be set, and
1823 mpq_set_ui (y, 17, 1);
1824 - mpfr_clear_erangeflag ();
1825 + mpfr_clear_flags ();
1826 res1 = mpfr_cmp_q (x, y);
1827 - if (res1 != 0 || mpfr_erangeflag_p () == 0)
1828 + if (res1 != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
1830 printf ("Error for mpfr_cmp_q (NaN, 17)\n");
1831 printf ("Return value: expected 0, got %d\n", res1);
1832 - printf ("Erange flag: expected set, got %d\n", mpfr_erangeflag_p ());
1833 + printf ("Expected flags:");
1834 + flags_out (MPFR_FLAGS_ERANGE);
1835 + printf ("Got flags: ");
1836 + flags_out (__gmpfr_flags);
1840 + /* Check the flags when y is NaN: the erange flags must be set, and
1842 + mpfr_set_ui (x, 42, MPFR_RNDN);
1843 + /* A NaN rational is represented by 0/0 (MPFR extension). */
1844 + mpz_set_ui (mpq_numref (y), 0);
1845 + mpz_set_ui (mpq_denref (y), 0);
1846 + mpfr_clear_flags ();
1847 + res1 = mpfr_cmp_q (x, y);
1848 + if (res1 != 0 || __gmpfr_flags != MPFR_FLAGS_ERANGE)
1850 + printf ("Error for mpfr_cmp_q (42, NaN)\n");
1851 + printf ("Return value: expected 0, got %d\n", res1);
1852 + printf ("Expected flags:");
1853 + flags_out (MPFR_FLAGS_ERANGE);
1854 + printf ("Got flags: ");
1855 + flags_out (__gmpfr_flags);
1859 @@ -341,6 +364,55 @@
1864 + /* check for y = 1/0 */
1865 + mpz_set_ui (mpq_numref (y), 1);
1866 + mpz_set_ui (mpq_denref (y), 0);
1867 + mpfr_set_ui (x, 1, MPFR_RNDN);
1868 + MPFR_ASSERTN(mpfr_cmp_q (x, y) < 0);
1869 + mpfr_set_inf (x, -1);
1870 + MPFR_ASSERTN(mpfr_cmp_q (x, y) < 0);
1871 + mpfr_set_inf (x, +1);
1872 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1874 + mpfr_clear_erangeflag ();
1875 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1876 + MPFR_ASSERTN(mpfr_erangeflag_p ());
1878 + /* check for y = -1/0 */
1879 + mpz_set_si (mpq_numref (y), -1);
1880 + mpz_set_ui (mpq_denref (y), 0);
1881 + mpfr_set_ui (x, 1, MPFR_RNDN);
1882 + MPFR_ASSERTN(mpfr_cmp_q (x, y) > 0);
1883 + mpfr_set_inf (x, -1);
1884 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1885 + mpfr_set_inf (x, +1);
1886 + MPFR_ASSERTN(mpfr_cmp_q (x, y) > 0);
1888 + mpfr_clear_erangeflag ();
1889 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1890 + MPFR_ASSERTN(mpfr_erangeflag_p ());
1892 + /* check for y = 0/0 */
1893 + mpz_set_ui (mpq_numref (y), 0);
1894 + mpz_set_ui (mpq_denref (y), 0);
1895 + mpfr_set_ui (x, 1, MPFR_RNDN);
1896 + mpfr_clear_erangeflag ();
1897 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1898 + MPFR_ASSERTN(mpfr_erangeflag_p ());
1899 + mpfr_set_inf (x, -1);
1900 + mpfr_clear_erangeflag ();
1901 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1902 + MPFR_ASSERTN(mpfr_erangeflag_p ());
1903 + mpfr_set_inf (x, +1);
1904 + mpfr_clear_erangeflag ();
1905 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1906 + MPFR_ASSERTN(mpfr_erangeflag_p ());
1908 + mpfr_clear_erangeflag ();
1909 + MPFR_ASSERTN(mpfr_cmp_q (x, y) == 0);
1910 + MPFR_ASSERTN(mpfr_erangeflag_p ());
1915 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
1916 --- mpfr-4.0.1-a/PATCHES 2018-04-27 12:54:17.862594948 +0000
1917 +++ mpfr-4.0.1-b/PATCHES 2018-04-27 12:54:17.894594642 +0000
1920 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
1921 --- mpfr-4.0.1-a/VERSION 2018-04-27 12:52:13.911782747 +0000
1922 +++ mpfr-4.0.1-b/VERSION 2018-04-27 12:54:17.894594642 +0000
1926 diff -Naurd mpfr-4.0.1-a/src/inp_str.c mpfr-4.0.1-b/src/inp_str.c
1927 --- mpfr-4.0.1-a/src/inp_str.c 2018-01-09 12:30:58.000000000 +0000
1928 +++ mpfr-4.0.1-b/src/inp_str.c 2018-04-27 12:54:17.882594757 +0000
1933 - if (stream == NULL)
1937 str = (unsigned char *) mpfr_allocate_func (alloc_size);
1939 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
1940 --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:52:13.907782785 +0000
1941 +++ mpfr-4.0.1-b/src/mpfr.h 2018-04-27 12:54:17.894594642 +0000
1943 #define MPFR_VERSION_MAJOR 4
1944 #define MPFR_VERSION_MINOR 0
1945 #define MPFR_VERSION_PATCHLEVEL 1
1946 -#define MPFR_VERSION_STRING "4.0.1-p5"
1947 +#define MPFR_VERSION_STRING "4.0.1-p6"
1950 MPFR_USE_FILE: Define it to make MPFR define functions dealing
1951 diff -Naurd mpfr-4.0.1-a/src/out_str.c mpfr-4.0.1-b/src/out_str.c
1952 --- mpfr-4.0.1-a/src/out_str.c 2018-01-09 12:30:58.000000000 +0000
1953 +++ mpfr-4.0.1-b/src/out_str.c 2018-04-27 12:54:17.882594757 +0000
1956 MPFR_ASSERTN (base >= 2 && base <= 62);
1958 - /* when stream=NULL, output to stdout */
1959 - if (stream == NULL)
1962 if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (op)))
1964 if (MPFR_IS_NAN (op))
1965 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
1966 --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:52:13.911782747 +0000
1967 +++ mpfr-4.0.1-b/src/version.c 2018-04-27 12:54:17.894594642 +0000
1970 mpfr_get_version (void)
1972 - return "4.0.1-p5";
1973 + return "4.0.1-p6";
1975 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
1976 --- mpfr-4.0.1-a/PATCHES 2018-07-10 15:29:07.937776370 +0000
1977 +++ mpfr-4.0.1-b/PATCHES 2018-07-10 15:29:08.017776303 +0000
1980 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
1981 --- mpfr-4.0.1-a/VERSION 2018-04-27 12:54:17.894594642 +0000
1982 +++ mpfr-4.0.1-b/VERSION 2018-07-10 15:29:08.017776303 +0000
1986 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
1987 --- mpfr-4.0.1-a/src/mpfr.h 2018-04-27 12:54:17.894594642 +0000
1988 +++ mpfr-4.0.1-b/src/mpfr.h 2018-07-10 15:29:08.013776307 +0000
1990 #define MPFR_VERSION_MAJOR 4
1991 #define MPFR_VERSION_MINOR 0
1992 #define MPFR_VERSION_PATCHLEVEL 1
1993 -#define MPFR_VERSION_STRING "4.0.1-p6"
1994 +#define MPFR_VERSION_STRING "4.0.1-p7"
1997 MPFR_USE_FILE: Define it to make MPFR define functions dealing
1998 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
1999 --- mpfr-4.0.1-a/src/version.c 2018-04-27 12:54:17.894594642 +0000
2000 +++ mpfr-4.0.1-b/src/version.c 2018-07-10 15:29:08.017776303 +0000
2003 mpfr_get_version (void)
2005 - return "4.0.1-p6";
2006 + return "4.0.1-p7";
2008 diff -Naurd mpfr-4.0.1-a/tests/tstckintc.c mpfr-4.0.1-b/tests/tstckintc.c
2009 --- mpfr-4.0.1-a/tests/tstckintc.c 2018-01-09 12:30:58.000000000 +0000
2010 +++ mpfr-4.0.1-b/tests/tstckintc.c 2018-07-10 15:29:07.989776327 +0000
2013 #define ALIGNED(s) (((s) + sizeof (long) - 1) / sizeof (long) * sizeof (long))
2015 +/* This code ensures alignment to "long". However, this might not be
2016 + sufficient on some platforms. GCC's -Wcast-align=strict option can
2017 + be useful, but this needs successive casts to help GCC, e.g.
2019 + newx = (mpfr_ptr) (long *) (void *) old_stack;
2021 + successively casts old_stack (of type char *) to
2022 + - void *: avoid a false positive for the following cast to long *
2023 + (as the code takes care of alignment to "long");
2024 + - long *: this corresponds to the alignment checked by MPFR; coming
2025 + from void *, it will not trigger a warning (even if incorrect);
2026 + - mpfr_ptr: -Wcast-align=strict will emit a warning if mpfr_ptr has
2027 + an alignment requirement stronger than long *. In such a case,
2028 + the code will have to be fixed.
2034 @@ -94,12 +110,14 @@
2035 void *mantissa = mpfr_custom_get_significand (x);
2036 size_t size_mantissa = mpfr_custom_get_size (mpfr_get_prec (x));
2040 memmove (old_stack, x, sizeof (mpfr_t));
2041 memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
2042 - newx = (mpfr_ptr) old_stack;
2043 - mpfr_custom_move (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
2044 - stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
2045 + newx = (mpfr_ptr) (long *) (void *) old_stack;
2046 + newx2 = (long *) (void *) (old_stack + ALIGNED (sizeof (mpfr_t)));
2047 + mpfr_custom_move (newx, newx2);
2048 + stack = (char *) newx2 + ALIGNED (size_mantissa);
2054 memmove (old_stack, x, sizeof (mpfr_t));
2055 memmove (old_stack + ALIGNED (sizeof (mpfr_t)), mantissa, size_mantissa);
2056 - newx = (mpfr_ptr) old_stack;
2057 + newx = (mpfr_ptr) (long *) (void *) old_stack;
2058 (mpfr_custom_move) (newx, old_stack + ALIGNED (sizeof (mpfr_t)));
2059 stack = old_stack + ALIGNED (sizeof (mpfr_t)) + ALIGNED (size_mantissa);
2065 - org = (long *) stack;
2066 + org = (long *) (void *) stack;
2074 - org = (long *) stack;
2075 + org = (long *) (void *) stack;
2077 a = dummy_set_si (42);
2078 b = dummy_set_si (17);
2079 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
2080 --- mpfr-4.0.1-a/PATCHES 2018-07-10 15:33:45.189532503 +0000
2081 +++ mpfr-4.0.1-b/PATCHES 2018-07-10 15:33:45.265532432 +0000
2084 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
2085 --- mpfr-4.0.1-a/VERSION 2018-07-10 15:29:08.017776303 +0000
2086 +++ mpfr-4.0.1-b/VERSION 2018-07-10 15:33:45.261532435 +0000
2090 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
2091 --- mpfr-4.0.1-a/src/mpfr.h 2018-07-10 15:29:08.013776307 +0000
2092 +++ mpfr-4.0.1-b/src/mpfr.h 2018-07-10 15:33:45.261532435 +0000
2094 #define MPFR_VERSION_MAJOR 4
2095 #define MPFR_VERSION_MINOR 0
2096 #define MPFR_VERSION_PATCHLEVEL 1
2097 -#define MPFR_VERSION_STRING "4.0.1-p7"
2098 +#define MPFR_VERSION_STRING "4.0.1-p8"
2101 MPFR_USE_FILE: Define it to make MPFR define functions dealing
2102 diff -Naurd mpfr-4.0.1-a/src/set_d64.c mpfr-4.0.1-b/src/set_d64.c
2103 --- mpfr-4.0.1-a/src/set_d64.c 2018-01-09 12:30:58.000000000 +0000
2104 +++ mpfr-4.0.1-b/src/set_d64.c 2018-07-10 15:33:45.237532458 +0000
2106 1 character for terminating \0. */
2108 decimal64_to_string (s, d);
2109 - return mpfr_set_str (r, s, 10, rnd_mode);
2110 + return mpfr_strtofr (r, s, NULL, 10, rnd_mode);
2113 #endif /* MPFR_WANT_DECIMAL_FLOATS */
2114 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
2115 --- mpfr-4.0.1-a/src/version.c 2018-07-10 15:29:08.017776303 +0000
2116 +++ mpfr-4.0.1-b/src/version.c 2018-07-10 15:33:45.261532435 +0000
2119 mpfr_get_version (void)
2121 - return "4.0.1-p7";
2122 + return "4.0.1-p8";
2124 diff -Naurd mpfr-4.0.1-a/tests/tget_set_d64.c mpfr-4.0.1-b/tests/tget_set_d64.c
2125 --- mpfr-4.0.1-a/tests/tget_set_d64.c 2018-01-09 12:30:58.000000000 +0000
2126 +++ mpfr-4.0.1-b/tests/tget_set_d64.c 2018-07-10 15:33:45.237532458 +0000
2127 @@ -381,6 +381,66 @@
2132 +powers_of_10 (void)
2139 + mpfr_inits2 (200, x1, x2, (mpfr_ptr) 0);
2140 + for (i = 0, d[0] = 1, d[1] = 1; i < 150; i++, d[0] *= 10, d[1] /= 10)
2141 + for (neg = 0; neg <= 3; neg++)
2142 + RND_LOOP_NO_RNDF (rnd)
2145 + mpfr_flags_t flags1, flags2;
2149 + inex1 = mpfr_set_si (x1, (neg >> 1) ? -i : i, MPFR_RNDN);
2150 + MPFR_ASSERTN (inex1 == 0);
2153 + MPFR_INVERT_RND ((mpfr_rnd_t) rnd) : (mpfr_rnd_t) rnd;
2154 + mpfr_clear_flags ();
2155 + inex1 = mpfr_exp10 (x1, x1, rx1);
2156 + flags1 = __gmpfr_flags;
2162 + MPFR_SET_NEG (x1);
2167 + mpfr_clear_flags ();
2168 + inex2 = mpfr_set_decimal64 (x2, dd, (mpfr_rnd_t) rnd);
2169 + flags2 = __gmpfr_flags;
2171 + if (!(mpfr_equal_p (x1, x2) &&
2172 + SAME_SIGN (inex1, inex2) &&
2173 + flags1 == flags2))
2175 + printf ("Error in powers_of_10 for i=%d, neg=%d, %s\n",
2176 + i, neg, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
2177 + printf ("Expected ");
2179 + printf ("with inex = %d and flags =", inex1);
2180 + flags_out (flags1);
2183 + printf ("with inex = %d and flags =", inex2);
2184 + flags_out (flags2);
2188 + mpfr_clears (x1, x2, (mpfr_ptr) 0);
2202 diff -Naurd mpfr-4.0.1-a/PATCHES mpfr-4.0.1-b/PATCHES
2203 --- mpfr-4.0.1-a/PATCHES 2018-07-10 15:46:13.596797032 +0000
2204 +++ mpfr-4.0.1-b/PATCHES 2018-07-10 15:46:13.676796949 +0000
2207 diff -Naurd mpfr-4.0.1-a/VERSION mpfr-4.0.1-b/VERSION
2208 --- mpfr-4.0.1-a/VERSION 2018-07-10 15:33:45.261532435 +0000
2209 +++ mpfr-4.0.1-b/VERSION 2018-07-10 15:46:13.676796949 +0000
2213 diff -Naurd mpfr-4.0.1-a/src/mpfr.h mpfr-4.0.1-b/src/mpfr.h
2214 --- mpfr-4.0.1-a/src/mpfr.h 2018-07-10 15:33:45.261532435 +0000
2215 +++ mpfr-4.0.1-b/src/mpfr.h 2018-07-10 15:46:13.672796954 +0000
2217 #define MPFR_VERSION_MAJOR 4
2218 #define MPFR_VERSION_MINOR 0
2219 #define MPFR_VERSION_PATCHLEVEL 1
2220 -#define MPFR_VERSION_STRING "4.0.1-p8"
2221 +#define MPFR_VERSION_STRING "4.0.1-p9"
2224 MPFR_USE_FILE: Define it to make MPFR define functions dealing
2225 diff -Naurd mpfr-4.0.1-a/src/vasprintf.c mpfr-4.0.1-b/src/vasprintf.c
2226 --- mpfr-4.0.1-a/src/vasprintf.c 2018-01-09 12:30:58.000000000 +0000
2227 +++ mpfr-4.0.1-b/src/vasprintf.c 2018-07-10 15:46:13.648796978 +0000
2228 @@ -683,20 +683,31 @@
2231 const size_t step = 3;
2232 - const size_t size = len + tz;
2233 - const size_t r = size % step == 0 ? step : size % step;
2234 - const size_t q = size % step == 0 ? size / step - 1 : size / step;
2235 - const size_t fullsize = size + q;
2237 + size_t size, q, r, fullsize;
2239 + /* check that len + tz does not overflow */
2240 + if (len > (size_t) -1 - tz)
2243 + size = len + tz; /* number of digits */
2244 MPFR_ASSERTD (size > 0);
2246 + q = (size - 1) / step; /* number of separators C */
2247 + r = ((size - 1) % step) + 1; /* number of digits in the leftmost block */
2249 + /* check that size + q does not overflow */
2250 + if (size > (size_t) -1 - q)
2253 + fullsize = size + q; /* number of digits and separators */
2255 if (buffer_incr_len (b, fullsize))
2263 MPFR_ASSERTD (*b->curr == '\0');
2264 MPFR_ASSERTN (b->size < ((size_t) -1) - fullsize);
2265 @@ -705,11 +716,21 @@
2267 MPFR_DBGRES (oldcurr = b->curr);
2269 - /* first R significant digits */
2270 - memcpy (b->curr, str, r);
2271 + /* first r significant digits (leftmost block) */
2274 + memcpy (b->curr, str, r);
2280 + MPFR_ASSERTD (r > len);
2281 + memcpy (b->curr, str, len);
2282 + memset (b->curr + len, '0', r - len);
2289 /* blocks of thousands. Warning: STR might end in the middle of a block */
2290 for (i = 0; i < q; ++i)
2293 memcpy (b->curr, str, step);
2298 /* last digits in STR, fill up thousand block with zeros */
2300 memset (b->curr, '0', step);
2306 MPFR_ASSERTD (b->curr - oldcurr == fullsize);
2307 @@ -1920,8 +1941,14 @@
2308 /* integral part (may also be "nan" or "inf") */
2309 MPFR_ASSERTN (np.ip_ptr != NULL); /* never empty */
2310 if (MPFR_UNLIKELY (np.thousands_sep))
2311 - buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
2312 - np.thousands_sep);
2314 + if (buffer_sandwich (buf, np.ip_ptr, np.ip_size, np.ip_trailing_zeros,
2315 + np.thousands_sep))
2318 + goto clear_and_exit;
2323 buffer_cat (buf, np.ip_ptr, np.ip_size);
2324 diff -Naurd mpfr-4.0.1-a/src/version.c mpfr-4.0.1-b/src/version.c
2325 --- mpfr-4.0.1-a/src/version.c 2018-07-10 15:33:45.261532435 +0000
2326 +++ mpfr-4.0.1-b/src/version.c 2018-07-10 15:46:13.672796954 +0000
2329 mpfr_get_version (void)
2331 - return "4.0.1-p8";
2332 + return "4.0.1-p9";
2334 diff -Naurd mpfr-4.0.1-a/tests/tprintf.c mpfr-4.0.1-b/tests/tprintf.c
2335 --- mpfr-4.0.1-a/tests/tprintf.c 2018-01-09 12:30:58.000000000 +0000
2336 +++ mpfr-4.0.1-b/tests/tprintf.c 2018-07-10 15:46:13.648796978 +0000
2341 +#ifdef HAVE_LOCALE_H
2342 +#include <locale.h>
2345 #include "mpfr-intmax.h"
2346 #include "mpfr-test.h"
2347 #define STDOUT_FILENO 1
2348 @@ -474,30 +478,41 @@
2352 -#ifdef HAVE_LOCALE_H
2354 -#include <locale.h>
2356 -const char * const tab_locale[] = {
2359 - "en_US.iso885915",
2362 +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
2367 + const char * const tab_locale[] = {
2370 + "en_US.iso885915",
2377 + char v[] = "99999999999999999999999.5";
2379 - for(i = 0; i < numberof(tab_locale) && s == NULL; i++)
2380 - s = setlocale (LC_ALL, tab_locale[i]);
2381 + for (i = 0; i < numberof(tab_locale); i++)
2385 - if (s == NULL || MPFR_THOUSANDS_SEPARATOR != ',')
2387 + s = setlocale (LC_ALL, tab_locale[i]);
2389 + if (s != NULL && MPFR_THOUSANDS_SEPARATOR == ',')
2393 + if (i == numberof(tab_locale))
2395 + if (getenv ("MPFR_CHECK_LOCALES") == NULL)
2398 + fprintf (stderr, "Cannot find a locale with ',' thousands separator.\n"
2399 + "Please install one of the en_US based locales.\n");
2403 mpfr_init2 (x, 113);
2404 mpfr_set_ui (x, 10000, MPFR_RNDN);
2405 @@ -507,6 +522,50 @@
2406 count = mpfr_printf ("(2) 10000=%'Rf \n", x);
2407 check_length (10001, count, 25, d);
2409 + mpfr_set_ui (x, 1000, MPFR_RNDN);
2410 + count = mpfr_printf ("(3) 1000=%'Rf \n", x);
2411 + check_length (10002, count, 23, d);
2413 + for (i = 1; i <= sizeof (v) - 3; i++)
2415 + mpfr_set_str (x, v + sizeof (v) - 3 - i, 10, MPFR_RNDN);
2416 + count = mpfr_printf ("(4) 10^i=%'.0Rf \n", x);
2417 + check_length (10002 + i, count, 12 + i + i/3, d);
2422 + for (i = 1; i <= N0; i++)
2428 + for (j = 1; j <= i; j++)
2432 + mpfr_set_str (x, s, 10, MPFR_RNDN);
2436 + count = mpfr_printf ("(5) 10^i=%'.0R*f \n", (mpfr_rnd_t) rnd, x);
2437 + check_length (11000 + 10 * i + rnd, count, 12 + i + i/3, d);
2440 + strcat (s + (i + 1), ".5");
2441 + count = mpfr_printf ("(5) 10^i=%'.0Rf \n", x);
2442 + check_length (11000 + 10 * i + 9, count, 12 + i + i/3, d);
2445 + mpfr_set_str (x, "1000", 10, MPFR_RNDN);
2446 + count = mpfr_printf ("%'012.3Rg\n", x);
2447 + check_length (12000, count, 13, d);
2448 + count = mpfr_printf ("%'012.4Rg\n", x);
2449 + check_length (12001, count, 13, d);
2450 + count = mpfr_printf ("%'013.4Rg\n", x);
2451 + check_length (12002, count, 14, d);
2456 @@ -515,7 +574,11 @@
2461 + if (getenv ("MPFR_CHECK_LOCALES") != NULL)
2463 + fprintf (stderr, "Cannot test locales.\n");
2469 diff -Naurd mpfr-4.0.1-a/tests/tsprintf.c mpfr-4.0.1-b/tests/tsprintf.c
2470 --- mpfr-4.0.1-a/tests/tsprintf.c 2018-01-10 10:15:30.000000000 +0000
2471 +++ mpfr-4.0.1-b/tests/tsprintf.c 2018-07-10 15:46:13.648796978 +0000
2473 check_sprintf ("1.00 ", "%-#20.3RG", x);
2474 check_sprintf ("0.9999 ", "%-#20.4RG", x);
2476 - /* multiple of 10 */
2477 + /* powers of 10 */
2478 mpfr_set_str (x, "1e17", 10, MPFR_RNDN);
2479 check_sprintf ("1e+17", "%Re", x);
2480 check_sprintf ("1.000e+17", "%.3Re", x);
2482 check_sprintf ("1", "%.0RUf", x);
2483 check_sprintf ("1", "%.0RYf", x);
2485 - /* multiple of 10 with 'g' style */
2486 + /* powers of 10 with 'g' style */
2487 mpfr_set_str (x, "10", 10, MPFR_RNDN);
2488 check_sprintf ("10", "%Rg", x);
2489 check_sprintf ("1e+01", "%.0Rg", x);
2490 @@ -419,6 +419,12 @@
2491 check_sprintf ("1e+03", "%.0Rg", x);
2492 check_sprintf ("1e+03", "%.3Rg", x);
2493 check_sprintf ("1000", "%.4Rg", x);
2494 + check_sprintf ("1e+03", "%.3Rg", x);
2495 + check_sprintf ("1000", "%.4Rg", x);
2496 + check_sprintf (" 1e+03", "%9.3Rg", x);
2497 + check_sprintf (" 1000", "%9.4Rg", x);
2498 + check_sprintf ("00001e+03", "%09.3Rg", x);
2499 + check_sprintf ("000001000", "%09.4Rg", x);
2501 mpfr_ui_div (x, 1, x, MPFR_RNDN);
2502 check_sprintf ("0.001", "%Rg", x);
2503 @@ -430,6 +436,10 @@
2504 check_sprintf ("1e+05", "%.0Rg", x);
2505 check_sprintf ("1e+05", "%.5Rg", x);
2506 check_sprintf ("100000", "%.6Rg", x);
2507 + check_sprintf (" 1e+05", "%17.5Rg", x);
2508 + check_sprintf (" 100000", "%17.6Rg", x);
2509 + check_sprintf ("0000000000001e+05", "%017.5Rg", x);
2510 + check_sprintf ("00000000000100000", "%017.6Rg", x);
2512 mpfr_ui_div (x, 1, x, MPFR_RNDN);
2513 check_sprintf ("1e-05", "%Rg", x);
2514 @@ -857,6 +867,12 @@
2515 "%.*Zi, %R*e, %Lf", 20, mpz, rnd, x, d);
2518 + /* check invalid spec.spec */
2519 + check_vsprintf ("%,", "%,");
2521 + /* check empty format */
2522 + check_vsprintf ("%", "%");
2527 @@ -864,12 +880,12 @@
2531 -#if MPFR_LCONV_DPTS
2532 +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && MPFR_LCONV_DPTS
2534 /* Check with locale "da_DK". On most platforms, decimal point is ','
2535 and thousands separator is '.'; the test is not performed if this
2536 is not the case or if the locale doesn't exist. */
2541 mpfr_prec_t p = 128;
2542 @@ -878,7 +894,16 @@
2543 if (setlocale (LC_ALL, "da_DK") == 0 ||
2544 localeconv()->decimal_point[0] != ',' ||
2545 localeconv()->thousands_sep[0] != '.')
2548 + setlocale (LC_ALL, "C");
2550 + if (getenv ("MPFR_CHECK_LOCALES") == NULL)
2554 + "Cannot test the da_DK locale (not found or inconsistent).\n");
2560 @@ -917,10 +942,11 @@
2561 check_sprintf ("100" S2 "0000", "%'.4Rf", x);
2566 + setlocale (LC_ALL, "C");
2569 -#endif /* MPFR_LCONV_DPTS */
2570 +#endif /* ... && MPFR_LCONV_DPTS */
2572 /* check concordance between mpfr_asprintf result with a regular mpfr float
2573 and with a regular double float */
2574 @@ -1425,6 +1451,117 @@
2578 +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
2580 +/* The following tests should be equivalent to those from test_locale()
2581 + in tprintf.c (remove the \n at the end of the test strings). */
2586 + const char * const tab_locale[] = {
2589 + "en_US.iso885915",
2594 + char v[] = "99999999999999999999999.5";
2596 + for (i = 0; i < numberof(tab_locale); i++)
2600 + s = setlocale (LC_ALL, tab_locale[i]);
2602 + if (s != NULL && MPFR_THOUSANDS_SEPARATOR == ',')
2606 + if (i == numberof(tab_locale))
2608 + if (getenv ("MPFR_CHECK_LOCALES") == NULL)
2611 + fprintf (stderr, "Cannot find a locale with ',' thousands separator.\n"
2612 + "Please install one of the en_US based locales.\n");
2616 + mpfr_init2 (x, 113);
2617 + mpfr_set_ui (x, 10000, MPFR_RNDN);
2619 + check_sprintf ("(1) 10000=10,000 ", "(1) 10000=%'Rg ", x);
2620 + check_sprintf ("(2) 10000=10,000.000000 ", "(2) 10000=%'Rf ", x);
2622 + mpfr_set_ui (x, 1000, MPFR_RNDN);
2623 + check_sprintf ("(3) 1000=1,000.000000 ", "(3) 1000=%'Rf ", x);
2625 + for (i = 1; i <= sizeof (v) - 3; i++)
2630 + strcpy (buf, "(4) 10^i=1");
2631 + for (j = i; j > 0; j--)
2632 + strcat (buf, ",0" + (j % 3 != 0));
2633 + strcat (buf, " ");
2634 + mpfr_set_str (x, v + sizeof (v) - 3 - i, 10, MPFR_RNDN);
2635 + check_sprintf (buf, "(4) 10^i=%'.0Rf ", x);
2640 + for (i = 1; i <= N0; i++)
2642 + char s[N0+4], buf[64];
2646 + for (j = 1; j <= i; j++)
2650 + strcpy (buf, "(5) 10^i=1");
2651 + for (j = i; j > 0; j--)
2652 + strcat (buf, ",0" + (j % 3 != 0));
2653 + strcat (buf, " ");
2655 + mpfr_set_str (x, s, 10, MPFR_RNDN);
2657 + check_sprintf (buf, "(5) 10^i=%'.0RNf ", x);
2658 + check_sprintf (buf, "(5) 10^i=%'.0RZf ", x);
2659 + check_sprintf (buf, "(5) 10^i=%'.0RUf ", x);
2660 + check_sprintf (buf, "(5) 10^i=%'.0RDf ", x);
2661 + check_sprintf (buf, "(5) 10^i=%'.0RYf ", x);
2663 + strcat (s + (i + 1), ".5");
2664 + check_sprintf (buf, "(5) 10^i=%'.0Rf ", x);
2667 + mpfr_set_str (x, "1000", 10, MPFR_RNDN);
2668 + check_sprintf ("00000001e+03", "%'012.3Rg", x);
2669 + check_sprintf ("00000001,000", "%'012.4Rg", x);
2670 + check_sprintf ("000000001,000", "%'013.4Rg", x);
2680 + if (getenv ("MPFR_CHECK_LOCALES") != NULL)
2682 + fprintf (stderr, "Cannot test locales.\n");
2690 main (int argc, char **argv)
2692 @@ -1446,12 +1583,14 @@
2696 -#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
2697 -#if MPFR_LCONV_DPTS
2698 +#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && MPFR_LCONV_DPTS
2700 - /* Avoid a warning by doing the setlocale outside of this #if */
2702 - setlocale (LC_ALL, "C");
2704 + if (getenv ("MPFR_CHECK_LOCALES") != NULL)
2706 + fprintf (stderr, "Cannot test locales.\n");
2712 @@ -1462,6 +1601,7 @@
2718 if (getenv ("MPFR_CHECK_LIBC_PRINTF"))