1
/* Test file for mpfr_rint, mpfr_trunc, mpfr_floor, mpfr_ceil, mpfr_round.
3
Copyright 2002, 2003, 2004, 2005 Free Software Foundation.
5
This file is part of the MPFR Library.
7
The MPFR Library is free software; you can redistribute it and/or modify
8
it under the terms of the GNU Lesser General Public License as published by
9
the Free Software Foundation; either version 2.1 of the License, or (at your
10
option) any later version.
12
The MPFR Library is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15
License for more details.
17
You should have received a copy of the GNU Lesser General Public License
18
along with the MPFR Library; see the file COPYING.LIB. If not, write to
19
the Free Software Foundation, Inc., 51 Franklin Place, Fifth Floor, Boston,
20
MA 02110-1301, USA. */
26
#include "mpfr-test.h"
28
#if __MPFR_STDC (199901L)
42
mpfr_rint (y, x, GMP_RNDN);
43
MPFR_ASSERTN(mpfr_nan_p (y));
46
mpfr_rint (y, x, GMP_RNDN);
47
MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
50
mpfr_rint (y, x, GMP_RNDN);
51
MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) < 0);
53
mpfr_set_ui (x, 0, GMP_RNDN);
54
mpfr_rint (y, x, GMP_RNDN);
55
MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));
57
mpfr_set_ui (x, 0, GMP_RNDN);
58
mpfr_neg (x, x, GMP_RNDN);
59
mpfr_rint (y, x, GMP_RNDN);
60
MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_NEG(y));
64
mpfr_set_ui (x, 1, GMP_RNDN);
65
mpfr_mul_2exp (x, x, mp_bits_per_limb, GMP_RNDN);
66
mpfr_rint (y, x, GMP_RNDN);
67
MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
69
/* another coverage test */
70
emax = mpfr_get_emax ();
73
mpfr_set_str_binary (x, "1.11E0");
75
mpfr_rint (y, x, GMP_RNDU); /* x rounds to 1.0E1=0.1E2 which overflows */
76
MPFR_ASSERTN(mpfr_inf_p (y) && mpfr_sgn (y) > 0);
80
mpfr_set_prec (x, 97);
81
mpfr_set_prec (y, 96);
82
mpfr_set_str_binary (x, "-0.1011111001101111000111011100011100000110110110110000000111010001000101001111101010101011010111100E97");
83
mpfr_rint (y, x, GMP_RNDN);
84
MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
86
mpfr_set_prec (x, 53);
87
mpfr_set_prec (y, 53);
88
mpfr_set_str_binary (x, "0.10101100000000101001010101111111000000011111010000010E-1");
89
mpfr_rint (y, x, GMP_RNDU);
90
MPFR_ASSERTN(mpfr_cmp_ui (y, 1) == 0);
91
mpfr_rint (y, x, GMP_RNDD);
92
MPFR_ASSERTN(mpfr_cmp_ui (y, 0) == 0 && MPFR_IS_POS(y));
94
mpfr_set_prec (x, 36);
96
mpfr_set_str_binary (x, "-11000110101010111111110111001.0000100");
97
mpfr_rint (y, x, GMP_RNDN);
98
mpfr_set_str_binary (x, "-11E27");
99
MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
101
mpfr_set_prec (x, 39);
102
mpfr_set_prec (y, 29);
103
mpfr_set_str_binary (x, "-0.100010110100011010001111001001001100111E39");
104
mpfr_rint (y, x, GMP_RNDN);
105
mpfr_set_str_binary (x, "-0.10001011010001101000111100101E39");
106
MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
108
mpfr_set_prec (x, 46);
109
mpfr_set_prec (y, 32);
110
mpfr_set_str_binary (x, "-0.1011100110100101000001011111101011001001101001E32");
111
mpfr_rint (y, x, GMP_RNDN);
112
mpfr_set_str_binary (x, "-0.10111001101001010000010111111011E32");
113
MPFR_ASSERTN(mpfr_cmp (y, x) == 0);
115
/* coverage test for mpfr_round */
116
mpfr_set_prec (x, 3);
117
mpfr_set_str_binary (x, "1.01E1"); /* 2.5 */
118
mpfr_set_prec (y, 2);
120
/* since mpfr_round breaks ties away, should give 3 and not 2 as with
121
the "round to even" rule */
122
MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
123
/* same test for the function */
125
MPFR_ASSERTN(mpfr_cmp_ui (y, 3) == 0);
127
mpfr_set_prec (x, 6);
128
mpfr_set_prec (y, 3);
129
mpfr_set_str_binary (x, "110.111");
131
if (mpfr_cmp_ui (y, 7))
133
printf ("Error in round(110.111)\n");
137
/* Bug found by Mark J Watkins */
138
mpfr_set_prec (x, 84);
139
mpfr_set_str_binary (x,
140
"0.110011010010001000000111101101001111111100101110010000000000000" \
141
"000000000000000000000E32");
143
if (mpfr_cmp_str (x, "0.1100110100100010000001111011010100000000000000" \
144
"00000000000000000000000000000000000000E32", 2, GMP_RNDN))
146
printf ("Rounding error when dest=src\n");
154
#if __MPFR_STDC (199901L)
157
test_fct (double (*f)(double), int (*g)(), char *s, mp_rnd_t r)
164
for (d = -5.0; d <= 5.0; d += 0.25)
166
mpfr_set_d (dd, d, r);
169
mpfr_rint (yy, dd, r);
172
mpfr_set_d (dd, y, r);
173
if (mpfr_cmp (yy, dd))
175
printf ("test_against_libc: incorrect result for %s, rnd = %s,"
176
" d = %g\ngot ", s, mpfr_print_rnd_mode (r), d);
177
mpfr_out_str (stdout, 10, 0, yy, GMP_RNDN);
178
printf (" instead of %g\n", y);
186
#define TEST_FCT(F) test_fct (&F, &mpfr_##F, #F, r)
189
test_against_libc (void)
191
mp_rnd_t r = GMP_RNDN;
206
for (r = 0; r < GMP_RND_MAX ; r++)
207
if (mpfr_set_machine_rnd_mode (r) == 0)
208
test_fct (&nearbyint, &mpfr_rint, "rint", r);
215
err (char *str, mp_size_t s, mpfr_t x, mpfr_t y, mp_prec_t p, mp_rnd_t r,
216
int trint, int inexact)
218
printf ("Error: %s\ns = %u, p = %u, r = %s, trint = %d, inexact = %d\nx = ",
219
str, (unsigned int) s, (unsigned int) p, mpfr_print_rnd_mode (r),
221
mpfr_print_binary (x);
223
mpfr_print_binary (y);
229
main (int argc, char *argv[])
234
mpfr_t x, y, t, u, v;
247
for (s = 2; s < 100; s++)
249
/* z has exactly s bits */
251
mpz_mul_2exp (z, z, 1);
253
mpz_add_ui (z, z, 1);
254
mpfr_set_prec (x, s);
255
mpfr_set_prec (t, s);
256
mpfr_set_prec (u, s);
257
if (mpfr_set_z (x, z, GMP_RNDN))
259
printf ("Error: mpfr_set_z should be exact (s = %u)\n",
264
mpfr_neg (x, x, GMP_RNDN);
266
mpfr_div_2ui (x, x, randlimb () % s, GMP_RNDN);
267
for (p = 2; p < 100; p++)
270
mpfr_set_prec (y, p);
271
mpfr_set_prec (v, p);
272
for (r = 0; r < GMP_RND_MAX ; r++)
273
for (trint = 0; trint < 3; trint++)
276
inexact = mpfr_rint (y, x, (mp_rnd_t) r);
277
else if (r == GMP_RNDN)
278
inexact = mpfr_round (y, x);
279
else if (r == GMP_RNDZ)
280
inexact = (trint ? mpfr_trunc (y, x) :
281
mpfr_rint_trunc (y, x, GMP_RNDZ));
282
else if (r == GMP_RNDU)
283
inexact = (trint ? mpfr_ceil (y, x) :
284
mpfr_rint_ceil (y, x, GMP_RNDU));
285
else /* r = GMP_RNDD */
286
inexact = (trint ? mpfr_floor (y, x) :
287
mpfr_rint_floor (y, x, GMP_RNDD));
288
if (mpfr_sub (t, y, x, GMP_RNDN))
289
err ("subtraction 1 should be exact",
290
s, x, y, p, (mp_rnd_t) r, trint, inexact);
291
sign_t = mpfr_cmp_ui (t, 0);
293
(((inexact == 0) && (sign_t != 0)) ||
294
((inexact < 0) && (sign_t >= 0)) ||
295
((inexact > 0) && (sign_t <= 0))))
296
err ("wrong inexact flag", s, x, y, p, (mp_rnd_t) r, trint, inexact);
298
continue; /* end of the test for exact results */
300
if (((r == GMP_RNDD || (r == GMP_RNDZ && MPFR_SIGN (x) > 0))
302
((r == GMP_RNDU || (r == GMP_RNDZ && MPFR_SIGN (x) < 0))
304
err ("wrong rounding direction",
305
s, x, y, p, (mp_rnd_t) r, trint, inexact);
308
mpfr_add_ui (v, y, 1, GMP_RNDU);
309
if (mpfr_cmp (v, x) <= 0)
310
err ("representable integer between x and its "
311
"rounded value", s, x, y, p, (mp_rnd_t) r, trint, inexact);
315
mpfr_sub_ui (v, y, 1, GMP_RNDD);
316
if (mpfr_cmp (v, x) >= 0)
317
err ("representable integer between x and its "
318
"rounded value", s, x, y, p, (mp_rnd_t) r, trint, inexact);
323
if (mpfr_sub (u, v, x, GMP_RNDN))
324
err ("subtraction 2 should be exact",
325
s, x, y, p, (mp_rnd_t) r, trint, inexact);
326
cmp = mpfr_cmp_abs (t, u);
328
err ("faithful rounding, but not the nearest integer",
329
s, x, y, p, (mp_rnd_t) r, trint, inexact);
332
/* |t| = |u|: x is the middle of two consecutive
333
representable integers. */
336
/* halfway case for mpfr_rint in GMP_RNDN rounding
337
mode: round to an even integer or mantissa. */
338
mpfr_div_2ui (y, y, 1, GMP_RNDZ);
339
if (!mpfr_integer_p (y))
340
err ("halfway case for mpfr_rint, result isn't an"
341
" even integer", s, x, y, p, (mp_rnd_t) r, trint, inexact);
342
/* If floor(x) and ceil(x) aren't both representable
343
integers, the mantissa must be even. */
344
mpfr_sub (v, v, y, GMP_RNDN);
345
mpfr_abs (v, v, GMP_RNDN);
346
if (mpfr_cmp_ui (v, 1) != 0)
348
mpfr_div_2si (y, y, MPFR_EXP (y) - MPFR_PREC (y)
350
if (!mpfr_integer_p (y))
351
err ("halfway case for mpfr_rint, mantissa isn't"
352
" even", s, x, y, p, (mp_rnd_t) r, trint, inexact);
356
{ /* halfway case for mpfr_round: x must have been
357
rounded away from zero. */
358
if ((MPFR_SIGN (x) > 0 && inexact < 0) ||
359
(MPFR_SIGN (x) < 0 && inexact > 0))
360
err ("halfway case for mpfr_round, bad rounding"
361
" direction", s, x, y, p, (mp_rnd_t) r, trint, inexact);
376
#if __MPFR_STDC (199901L)
377
if (argc > 1 && strcmp (argv[1], "-s") == 0)
378
test_against_libc ();