1 /* Test file for mpfr_rint, mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round,
2 mpfr_rint_trunc, mpfr_rint_floor, mpfr_rint_ceil, mpfr_rint_round.
3
4 Copyright 2002-2023 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramba projects, INRIA.
6
7 This file is part of the GNU MPFR Library.
8
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
18
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23
24 #include "mpfr-test.h"
25
26 #if __MPFR_STDC (199901L)
27 # include <math.h>
28 #endif
29
30 static void
special(void)31 special (void)
32 {
33 mpfr_t x, y;
34 mpfr_exp_t emax;
35
36 mpfr_init (x);
37 mpfr_init (y);
38
39 mpfr_set_nan (x);
40 mpfr_rint (y, x, MPFR_RNDN);
41 MPFR_ASSERTN(mpfr_nan_p (y));
42
43 mpfr_set_inf (x, 1);
44 mpfr_rint (y, x, MPFR_RNDN);
45 MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
46
47 mpfr_set_inf (x, -1);
48 mpfr_rint (y, x, MPFR_RNDN);
49 MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
50
51 mpfr_set_ui (x, 0, MPFR_RNDN);
52 mpfr_rint (y, x, MPFR_RNDN);
53 MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));
54
55 mpfr_set_ui (x, 0, MPFR_RNDN);
56 mpfr_neg (x, x, MPFR_RNDN);
57 mpfr_rint (y, x, MPFR_RNDN);
58 MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG(y));
59
60 /* coverage test */
61 mpfr_set_prec (x, 2);
62 mpfr_set_ui (x, 1, MPFR_RNDN);
63 mpfr_mul_2ui (x, x, mp_bits_per_limb, MPFR_RNDN);
64 mpfr_rint (y, x, MPFR_RNDN);
65 MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
66
67 /* another coverage test */
68 emax = mpfr_get_emax ();
69 set_emax (1);
70 mpfr_set_prec (x, 3);
71 mpfr_set_str_binary (x, "1.11E0");
72 mpfr_set_prec (y, 2);
73 mpfr_rint (y, x, MPFR_RNDU); /* x rounds to 1.0E1=0.1E2 which overflows */
74 MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
75 set_emax (emax);
76
77 /* yet another */
78 mpfr_set_prec (x, 97);
79 mpfr_set_prec (y, 96);
80 mpfr_set_str_binary (x, "-0.1011111001101111000111011100011100000110110110110000000111010001000101001111101010101011010111100E97");
81 mpfr_rint (y, x, MPFR_RNDN);
82 MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
83
84 mpfr_set_prec (x, 53);
85 mpfr_set_prec (y, 53);
86 mpfr_set_str_binary (x, "0.10101100000000101001010101111111000000011111010000010E-1");
87 mpfr_rint (y, x, MPFR_RNDU);
88 MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
89 mpfr_rint (y, x, MPFR_RNDD);
90 MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));
91
92 mpfr_set_prec (x, 36);
93 mpfr_set_prec (y, 2);
94 mpfr_set_str_binary (x, "-11000110101010111111110111001.0000100");
95 mpfr_rint (y, x, MPFR_RNDN);
96 mpfr_set_str_binary (x, "-11E27");
97 MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
98
99 mpfr_set_prec (x, 39);
100 mpfr_set_prec (y, 29);
101 mpfr_set_str_binary (x, "-0.100010110100011010001111001001001100111E39");
102 mpfr_rint (y, x, MPFR_RNDN);
103 mpfr_set_str_binary (x, "-0.10001011010001101000111100101E39");
104 MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
105
106 mpfr_set_prec (x, 46);
107 mpfr_set_prec (y, 32);
108 mpfr_set_str_binary (x, "-0.1011100110100101000001011111101011001001101001E32");
109 mpfr_rint (y, x, MPFR_RNDN);
110 mpfr_set_str_binary (x, "-0.10111001101001010000010111111011E32");
111 MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
112
113 /* coverage test for mpfr_round */
114 mpfr_set_prec (x, 3);
115 mpfr_set_str_binary (x, "1.01E1"); /* 2.5 */
116 mpfr_set_prec (y, 2);
117 mpfr_round (y, x);
118 /* since mpfr_round breaks ties away, should give 3 and not 2 as with
119 the "round to even" rule */
120 MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
121 /* same test for the function */
122 (mpfr_round) (y, x);
123 MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
124
125 mpfr_set_prec (x, 6);
126 mpfr_set_prec (y, 3);
127 mpfr_set_str_binary (x, "110.111");
128 mpfr_round (y, x);
129 if (mpfr_cmp_ui (y, 7))
130 {
131 printf ("Error in round(110.111)\n");
132 exit (1);
133 }
134
135 /* Bug found by Mark J Watkins */
136 mpfr_set_prec (x, 84);
137 mpfr_set_str_binary (x,
138 "0.110011010010001000000111101101001111111100101110010000000000000" \
139 "000000000000000000000E32");
140 mpfr_round (x, x);
141 if (mpfr_cmp_str (x, "0.1100110100100010000001111011010100000000000000" \
142 "00000000000000000000000000000000000000E32", 2, MPFR_RNDN))
143 {
144 printf ("Rounding error when dest=src\n");
145 exit (1);
146 }
147
148 mpfr_clear (x);
149 mpfr_clear (y);
150 }
151
152 #define BASIC_TEST(F,J) \
153 do \
154 { \
155 int red; \
156 for (red = 0; red <= 1; red++) \
157 { \
158 int inex1, inex2; \
159 unsigned int ex_flags, flags; \
160 \
161 if (red) \
162 { \
163 set_emin (e); \
164 set_emax (e); \
165 } \
166 \
167 mpfr_clear_flags (); \
168 inex1 = mpfr_set_si (y, J, (mpfr_rnd_t) r); \
169 ex_flags = __gmpfr_flags; \
170 mpfr_clear_flags (); \
171 inex2 = mpfr_rint_##F (z, x, (mpfr_rnd_t) r); \
172 flags = __gmpfr_flags; \
173 if (! (mpfr_equal_p (y, z) && \
174 SAME_SIGN (inex1, inex2) && \
175 flags == ex_flags)) \
176 { \
177 printf ("Basic test failed on mpfr_rint_" #F \
178 ", prec = %d, i = %d, %s\n", prec, s * i, \
179 mpfr_print_rnd_mode ((mpfr_rnd_t) r)); \
180 printf ("i.e. x = "); \
181 mpfr_dump (x); \
182 if (red) \
183 printf ("with emin = emax = %d\n", e); \
184 printf ("Expected "); \
185 mpfr_dump (y); \
186 printf ("with inex = %d (or equivalent)\n", inex1); \
187 printf (" flags:"); \
188 flags_out (ex_flags); \
189 printf ("Got "); \
190 mpfr_dump (z); \
191 printf ("with inex = %d (or equivalent)\n", inex2); \
192 printf (" flags:"); \
193 flags_out (flags); \
194 exit (1); \
195 } \
196 } \
197 set_emin (emin); \
198 set_emax (emax); \
199 } \
200 while (0)
201
202 #define BASIC_TEST2(F,J,INEX) \
203 do \
204 { \
205 int red; \
206 for (red = 0; red <= 1; red++) \
207 { \
208 int inex; \
209 unsigned int ex_flags, flags; \
210 \
211 if (red) \
212 { \
213 set_emin (e); \
214 set_emax (e); \
215 } \
216 \
217 mpfr_clear_flags (); \
218 inex = mpfr_set_si (y, J, MPFR_RNDN); \
219 MPFR_ASSERTN (inex == 0 || mpfr_overflow_p ()); \
220 ex_flags = __gmpfr_flags; \
221 mpfr_clear_flags (); \
222 inex = mpfr_##F (z, x); \
223 if (inex != 0) \
224 ex_flags |= MPFR_FLAGS_INEXACT; \
225 flags = __gmpfr_flags; \
226 if (! (mpfr_equal_p (y, z) && \
227 inex == (INEX) && \
228 flags == ex_flags)) \
229 { \
230 printf ("Basic test failed on mpfr_" #F \
231 ", prec = %d, i = %d\n", prec, s * i); \
232 printf ("i.e. x = "); \
233 mpfr_dump (x); \
234 if (red) \
235 printf ("with emin = emax = %d\n", e); \
236 printf ("Expected "); \
237 mpfr_dump (y); \
238 printf ("with inex = %d\n", (INEX)); \
239 printf (" flags:"); \
240 flags_out (ex_flags); \
241 printf ("Got "); \
242 mpfr_dump (z); \
243 printf ("with inex = %d\n", inex); \
244 printf (" flags:"); \
245 flags_out (flags); \
246 exit (1); \
247 } \
248 } \
249 set_emin (emin); \
250 set_emax (emax); \
251 } \
252 while (0)
253
254 /* Test mpfr_rint_* on i/4 with |i| between 1 and 72. */
255 static void
basic_tests(void)256 basic_tests (void)
257 {
258 mpfr_t x, y, z;
259 int prec, s, i, r;
260 mpfr_exp_t emin, emax;
261
262 emin = mpfr_get_emin ();
263 emax = mpfr_get_emax ();
264
265 mpfr_init2 (x, 16);
266 for (prec = MPFR_PREC_MIN; prec <= 7; prec++)
267 {
268 mpfr_inits2 (prec, y, z, (mpfr_ptr) 0);
269 for (s = 1; s >= -1; s -= 2)
270 for (i = 1; i <= 72; i++)
271 {
272 int k, t, u, v, f, e, b;
273
274 for (t = i/4, k = 0; t >= 1 << prec; t >>= 1, k++)
275 ;
276 b = !(t & 1);
277 t <<= k;
278 for (u = (i+3)/4, k = 0; u >= 1 << prec; u = (u+1)/2, k++)
279 ;
280 u <<= k;
281 v = i < (t+u) << 1 ? t : u;
282 if (b)
283 b = i == (t+u) << 1;
284 f = t == u ? 0 : i % 4 == 0 ? 1 : 2;
285
286 mpfr_set_si_2exp (x, s * i, -2, MPFR_RNDN);
287 e = mpfr_get_exp (x);
288 RND_LOOP_NO_RNDF (r)
289 {
290 BASIC_TEST (trunc, s * (i/4));
291 BASIC_TEST (floor, s > 0 ? i/4 : - ((i+3)/4));
292 BASIC_TEST (ceil, s > 0 ? (i+3)/4 : - (i/4));
293 BASIC_TEST (round, s * ((i+2)/4));
294 BASIC_TEST (roundeven, s * (i % 8 == 2 ? i/4 : (i+2)/4));
295 }
296 BASIC_TEST2 (trunc, s * t, - s * f);
297 BASIC_TEST2 (floor, s > 0 ? t : - u, - f);
298 BASIC_TEST2 (ceil, s > 0 ? u : - t, f);
299 BASIC_TEST2 (round, s * v, v == t ? - s * f : s * f);
300 BASIC_TEST2 (roundeven, s * (b ? t : v),
301 b || v == t ? - s * f : s * f);
302 }
303 mpfr_clears (y, z, (mpfr_ptr) 0);
304 }
305 mpfr_clear (x);
306 }
307
308 #if __MPFR_STDC (199901L)
309
310 typedef int (*F2)(mpfr_ptr, mpfr_srcptr);
311
312 /* The argument g below will be of type F2 with args (mpfr_ptr, mpfr_srcptr),
313 except for mpfr_rint, with args (mpfr_ptr, mpfr_srcptr, mpfr_rnd_t). So,
314 when passing mpfr_rint, we need a cast: "(F2) &mpfr_rint". The cast will
315 also be needed to compare the pointers: "g == (F2) &mpfr_rint", and that's
316 all. */
317
318 #if defined(__GNUC__)
319 #pragma GCC diagnostic push
320 #if __GNUC__ >= 8 || __clang_major__ >= 13
321 #pragma GCC diagnostic ignored "-Wcast-function-type"
322 #endif
323 #endif
324
325 static void
test_fct(double (* f)(double),F2 g,const char * s,mpfr_rnd_t r)326 test_fct (double (*f)(double), F2 g, const char *s, mpfr_rnd_t r)
327 {
328 double d, y;
329 mpfr_t dd, yy;
330
331 mpfr_init2 (dd, 53);
332 mpfr_init2 (yy, 53);
333 for (d = -5.0; d <= 5.0; d += 0.25)
334 {
335 mpfr_set_d (dd, d, r);
336 y = (*f)(d);
337 if (g == (F2) &mpfr_rint)
338 mpfr_rint (yy, dd, r);
339 else
340 (*g)(yy, dd);
341 mpfr_set_d (dd, y, r);
342 if (mpfr_cmp (yy, dd))
343 {
344 printf ("test_against_libc: incorrect result for %s, rnd = %s,"
345 " d = %g\ngot ", s, mpfr_print_rnd_mode (r), d);
346 mpfr_out_str (stdout, 10, 0, yy, MPFR_RNDN);
347 printf (" instead of %g\n", y);
348 exit (1);
349 }
350 }
351 mpfr_clear (dd);
352 mpfr_clear (yy);
353 }
354
355 #define TEST_FCT(F) test_fct (&F, &mpfr_##F, #F, (mpfr_rnd_t) r)
356
357 static void
test_against_libc(void)358 test_against_libc (void)
359 {
360 int r = MPFR_RNDN;
361
362 (void) r; /* avoid a warning by using r */
363 #if HAVE_ROUND
364 TEST_FCT (round);
365 #endif
366 #if HAVE_TRUNC
367 TEST_FCT (trunc);
368 #endif
369 #if HAVE_FLOOR
370 TEST_FCT (floor);
371 #endif
372 #if HAVE_CEIL
373 TEST_FCT (ceil);
374 #endif
375 #if HAVE_NEARBYINT
376 RND_LOOP (r)
377 if (mpfr_set_machine_rnd_mode ((mpfr_rnd_t) r) == 0)
378 test_fct (&nearbyint, (F2) &mpfr_rint, "rint", (mpfr_rnd_t) r);
379 #endif
380 }
381
382 #if defined(__GNUC__)
383 #pragma GCC diagnostic pop
384 #endif
385
386 #endif
387
388 static void
err(const char * str,mp_size_t s,mpfr_ptr x,mpfr_ptr y,mpfr_prec_t p,mpfr_rnd_t r,int trint,int inexact)389 err (const char *str, mp_size_t s, mpfr_ptr x, mpfr_ptr y, mpfr_prec_t p,
390 mpfr_rnd_t r, int trint, int inexact)
391 {
392 printf ("Error: %s\ns = %u, p = %u, r = %s, trint = %d, inexact = %d\nx = ",
393 str, (unsigned int) s, (unsigned int) p, mpfr_print_rnd_mode (r),
394 trint, inexact);
395 mpfr_dump (x);
396 printf ("y = ");
397 mpfr_dump (y);
398 exit (1);
399 }
400
401 static void
coverage_03032011(void)402 coverage_03032011 (void)
403 {
404 mpfr_t in, out, cmp;
405 int status;
406 int precIn;
407 char strData[(GMP_NUMB_BITS * 4)+256];
408
409 precIn = GMP_NUMB_BITS * 4;
410
411 mpfr_init2 (in, precIn);
412 mpfr_init2 (out, GMP_NUMB_BITS);
413 mpfr_init2 (cmp, GMP_NUMB_BITS);
414
415 /* cmp = "0.1EprecIn+2" */
416 /* The buffer size is sufficient, as precIn is small in practice. */
417 sprintf (strData, "0.1E%d", precIn+2);
418 mpfr_set_str_binary (cmp, strData);
419
420 /* in = "0.10...01EprecIn+2" use all (precIn) significand bits */
421 memset ((void *)strData, '0', precIn+2);
422 strData[1] = '.';
423 strData[2] = '1';
424 sprintf (&strData[precIn+1], "1E%d", precIn+2);
425 mpfr_set_str_binary (in, strData);
426
427 status = mpfr_rint (out, in, MPFR_RNDN);
428 if ((mpfr_cmp (out, cmp) != 0) || (status >= 0))
429 {
430 printf("mpfr_rint error :\n status is %d instead of 0\n", status);
431 printf(" out value is ");
432 mpfr_dump(out);
433 printf(" instead of ");
434 mpfr_dump(cmp);
435 exit (1);
436 }
437
438 mpfr_clear (cmp);
439 mpfr_clear (out);
440
441 mpfr_init2 (out, GMP_NUMB_BITS);
442 mpfr_init2 (cmp, GMP_NUMB_BITS);
443
444 /* cmp = "0.10...01EprecIn+2" use all (GMP_NUMB_BITS) significand bits */
445 strcpy (&strData[GMP_NUMB_BITS+1], &strData[precIn+1]);
446 mpfr_set_str_binary (cmp, strData);
447
448 (MPFR_MANT(in))[2] = MPFR_LIMB_HIGHBIT;
449 status = mpfr_rint (out, in, MPFR_RNDN);
450
451 if ((mpfr_cmp (out, cmp) != 0) || (status <= 0))
452 {
453 printf("mpfr_rint error :\n status is %d instead of 0\n", status);
454 printf(" out value is\n");
455 mpfr_dump(out);
456 printf(" instead of\n");
457 mpfr_dump(cmp);
458 exit (1);
459 }
460
461 mpfr_clear (cmp);
462 mpfr_clear (out);
463 mpfr_clear (in);
464 }
465
466 #define TEST_FUNCTION mpfr_rint_trunc
467 #define TEST_RANDOM_EMIN -20
468 #define TEST_RANDOM_ALWAYS_SCALE 1
469 #define test_generic test_generic_trunc
470 #include "tgeneric.c"
471
472 #define TEST_FUNCTION mpfr_rint_floor
473 #define TEST_RANDOM_EMIN -20
474 #define TEST_RANDOM_ALWAYS_SCALE 1
475 #define test_generic test_generic_floor
476 #include "tgeneric.c"
477
478 #define TEST_FUNCTION mpfr_rint_ceil
479 #define TEST_RANDOM_EMIN -20
480 #define TEST_RANDOM_ALWAYS_SCALE 1
481 #define test_generic test_generic_ceil
482 #include "tgeneric.c"
483
484 #define TEST_FUNCTION mpfr_rint_round
485 #define TEST_RANDOM_EMIN -20
486 #define TEST_RANDOM_ALWAYS_SCALE 1
487 #define test_generic test_generic_round
488 #include "tgeneric.c"
489
490 #define TEST_FUNCTION mpfr_rint_roundeven
491 #define TEST_RANDOM_EMIN -20
492 #define TEST_RANDOM_ALWAYS_SCALE 1
493 #define test_generic test_generic_roundeven
494 #include "tgeneric.c"
495
496 int
main(int argc,char * argv[])497 main (int argc, char *argv[])
498 {
499 mp_size_t s;
500 mpz_t z;
501 mpfr_prec_t p;
502 mpfr_t x, y, t, u, v;
503 int r;
504 int inexact, sign_t;
505
506 tests_start_mpfr ();
507
508 mpfr_init (x);
509 mpfr_init (y);
510 mpz_init (z);
511 mpfr_init (t);
512 mpfr_init (u);
513 mpfr_init (v);
514 mpz_set_ui (z, 1);
515 /* the code below works for 1 <= MPFR_PREC_MIN <= 2 */
516 MPFR_ASSERTN(1 <= MPFR_PREC_MIN && MPFR_PREC_MIN <= 2);
517 for (s = MPFR_PREC_MIN; s < 100; s++)
518 {
519 if (s > 1)
520 {
521 mpz_mul_2exp (z, z, 1);
522 if (RAND_BOOL ())
523 mpz_add_ui (z, z, 1);
524 }
525 /* now 2^(s-1) <= z < 2^s */
526 mpfr_set_prec (x, s);
527 mpfr_set_prec (t, s);
528 mpfr_set_prec (u, s);
529 if (mpfr_set_z (x, z, MPFR_RNDN))
530 {
531 #ifndef MPFR_USE_MINI_GMP
532 gmp_printf ("Error: mpfr_set_z should be exact (z = %Zd, s = %u)\n",
533 z, (unsigned int) s);
534 #else /* mini-gmp has no gmp_printf (at least in gmp-6.1.2) */
535 printf ("mpfr_set_z should be exact\n");
536 #endif
537 exit (1);
538 }
539 if (RAND_BOOL ())
540 mpfr_neg (x, x, MPFR_RNDN);
541 if (RAND_BOOL ())
542 mpfr_div_2ui (x, x, randlimb () % s, MPFR_RNDN);
543 for (p = MPFR_PREC_MIN; p < 100; p++)
544 {
545 int trint;
546 mpfr_set_prec (y, p);
547 mpfr_set_prec (v, p);
548 RND_LOOP (r)
549 for (trint = 0; trint < 4; trint++)
550 {
551 if (trint == 2)
552 inexact = mpfr_rint (y, x, (mpfr_rnd_t) r);
553 else if (trint == 3)
554 {
555 if (r != MPFR_RNDN)
556 continue;
557 inexact = mpfr_round (y, x);
558 }
559 else if (r == MPFR_RNDN)
560 inexact = (trint ? mpfr_roundeven (y, x) :
561 mpfr_rint_roundeven (y, x, MPFR_RNDZ));
562 else if (r == MPFR_RNDZ)
563 inexact = (trint ? mpfr_trunc (y, x) :
564 mpfr_rint_trunc (y, x, MPFR_RNDZ));
565 else if (r == MPFR_RNDU)
566 inexact = (trint ? mpfr_ceil (y, x) :
567 mpfr_rint_ceil (y, x, MPFR_RNDU));
568 else if (r == MPFR_RNDD)
569 inexact = (trint ? mpfr_floor (y, x) :
570 mpfr_rint_floor (y, x, MPFR_RNDD));
571 else
572 {
573 MPFR_ASSERTN (r == MPFR_RNDA || r == MPFR_RNDF);
574 continue;
575 }
576 if (mpfr_sub (t, y, x, MPFR_RNDN))
577 err ("subtraction 1 should be exact", s, x, y, p,
578 (mpfr_rnd_t) r, trint, inexact);
579 sign_t = mpfr_cmp_ui (t, 0);
580 if (trint != 0 &&
581 (((inexact == 0) && (sign_t != 0)) ||
582 ((inexact < 0) && (sign_t >= 0)) ||
583 ((inexact > 0) && (sign_t <= 0))))
584 err ("wrong inexact flag", s, x, y, p,
585 (mpfr_rnd_t) r, trint, inexact);
586 if (inexact == 0)
587 continue; /* end of the test for exact results */
588
589 if (((r == MPFR_RNDD || (r == MPFR_RNDZ && MPFR_IS_POS (x)))
590 && inexact > 0) ||
591 ((r == MPFR_RNDU || (r == MPFR_RNDZ && MPFR_IS_NEG (x)))
592 && inexact < 0))
593 err ("wrong rounding direction", s, x, y, p,
594 (mpfr_rnd_t) r, trint, inexact);
595 if (inexact < 0)
596 {
597 mpfr_add_ui (v, y, 1, MPFR_RNDU);
598 if (mpfr_cmp (v, x) <= 0)
599 err ("representable integer between x and "
600 "its rounded value", s, x, y, p,
601 (mpfr_rnd_t) r, trint, inexact);
602 }
603 else
604 {
605 mpfr_sub_ui (v, y, 1, MPFR_RNDD);
606 if (mpfr_cmp (v, x) >= 0)
607 err ("representable integer between x and "
608 "its rounded value", s, x, y, p,
609 (mpfr_rnd_t) r, trint, inexact);
610 }
611 if (r == MPFR_RNDN && trint != 0)
612 {
613 int cmp;
614 if (mpfr_sub (u, v, x, MPFR_RNDN))
615 err ("subtraction 2 should be exact", s, x, y, p,
616 (mpfr_rnd_t) r, trint, inexact);
617 cmp = mpfr_cmpabs (t, u);
618 if (cmp > 0)
619 err ("faithful rounding, but not the nearest integer",
620 s, x, y, p, (mpfr_rnd_t) r, trint, inexact);
621 if (cmp < 0)
622 continue;
623 /* |t| = |u|: x is the middle of two consecutive
624 representable integers. */
625 if (trint == 2)
626 {
627 /* halfway case for mpfr_rint in MPFR_RNDN rounding
628 mode: round to an even integer or significand. */
629 mpfr_div_2ui (y, y, 1, MPFR_RNDZ);
630 if (!mpfr_integer_p (y))
631 err ("halfway case for mpfr_rint, result isn't "
632 "an even integer", s, x, y, p,
633 (mpfr_rnd_t) r, trint, inexact);
634 if (p > 1)
635 {
636 /* For p > 1, if floor(x) and ceil(x) aren't
637 both representable integers, the significand
638 must be even. */
639 mpfr_sub (v, v, y, MPFR_RNDN);
640 mpfr_abs (v, v, MPFR_RNDN);
641 if (mpfr_cmp_ui (v, 1) != 0)
642 {
643 mpfr_div_2si (y, y, MPFR_EXP (y) -
644 MPFR_PREC (y) + 1, MPFR_RNDN);
645 if (!mpfr_integer_p (y))
646 err ("halfway case for mpfr_rint, "
647 "significand isn't even", s, x, y, p,
648 (mpfr_rnd_t) r, trint, inexact);
649 }
650 }
651 }
652 else if (trint == 3)
653 { /* halfway case for mpfr_round: x must have been
654 rounded away from zero. */
655 if ((MPFR_IS_POS (x) && inexact < 0) ||
656 (MPFR_IS_NEG (x) && inexact > 0))
657 err ("halfway case for mpfr_round, "
658 "bad rounding direction", s, x, y, p,
659 (mpfr_rnd_t) r, trint, inexact);
660 }
661 }
662 }
663 }
664 }
665 mpfr_clear (x);
666 mpfr_clear (y);
667 mpz_clear (z);
668 mpfr_clear (t);
669 mpfr_clear (u);
670 mpfr_clear (v);
671
672 special ();
673 basic_tests ();
674 coverage_03032011 ();
675
676 test_generic_trunc (MPFR_PREC_MIN, 300, 20);
677 test_generic_floor (MPFR_PREC_MIN, 300, 20);
678 test_generic_ceil (MPFR_PREC_MIN, 300, 20);
679 test_generic_round (MPFR_PREC_MIN, 300, 20);
680 test_generic_roundeven (MPFR_PREC_MIN, 300, 20);
681
682 #if __MPFR_STDC (199901L)
683 if (argc > 1 && strcmp (argv[1], "-s") == 0)
684 test_against_libc ();
685 #endif
686
687 tests_end_mpfr ();
688 return 0;
689 }
690