tcan_round.c revision 1.1.1.3.4.1 1 1.1.1.3 mrg /* Test file for mpfr_can_round and mpfr_round_p.
2 1.1 mrg
3 1.1.1.3.4.1 christos Copyright 1999, 2001-2018 Free Software Foundation, Inc.
4 1.1.1.3 mrg Contributed by the AriC and Caramba projects, INRIA.
5 1.1 mrg
6 1.1 mrg This file is part of the GNU MPFR Library.
7 1.1 mrg
8 1.1 mrg The GNU MPFR Library is free software; you can redistribute it and/or modify
9 1.1 mrg it under the terms of the GNU Lesser General Public License as published by
10 1.1 mrg the Free Software Foundation; either version 3 of the License, or (at your
11 1.1 mrg option) any later version.
12 1.1 mrg
13 1.1 mrg The GNU MPFR Library is distributed in the hope that it will be useful, but
14 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 1.1 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 1.1 mrg License for more details.
17 1.1 mrg
18 1.1 mrg You should have received a copy of the GNU Lesser General Public License
19 1.1 mrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
20 1.1 mrg http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 1.1 mrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22 1.1 mrg
23 1.1 mrg #include "mpfr-test.h"
24 1.1 mrg
25 1.1.1.3 mrg /* Simple cases where err - prec is large enough.
26 1.1.1.3 mrg One can get failures as a consequence of r9883. */
27 1.1.1.3 mrg static void
28 1.1.1.3 mrg test_simple (void)
29 1.1.1.3 mrg {
30 1.1.1.3 mrg int t[4] = { 2, 3, -2, -3 }; /* test powers of 2 and non-powers of 2 */
31 1.1.1.3 mrg int i;
32 1.1.1.3 mrg int r1, r2;
33 1.1.1.3 mrg
34 1.1.1.3 mrg for (i = 0; i < 4; i++)
35 1.1.1.3 mrg RND_LOOP (r1)
36 1.1.1.3 mrg RND_LOOP (r2)
37 1.1.1.3 mrg {
38 1.1.1.3 mrg mpfr_t b;
39 1.1.1.3 mrg int p, err, prec, inex, c;
40 1.1.1.3 mrg
41 1.1.1.3.4.1 christos if (r2 == MPFR_RNDF)
42 1.1.1.3.4.1 christos continue;
43 1.1.1.3 mrg p = 12 + (randlimb() % (2 * GMP_NUMB_BITS));
44 1.1.1.3 mrg err = p - 3;
45 1.1.1.3 mrg prec = 4;
46 1.1.1.3 mrg mpfr_init2 (b, p);
47 1.1.1.3 mrg inex = mpfr_set_si (b, t[i], MPFR_RNDN);
48 1.1.1.3 mrg MPFR_ASSERTN (inex == 0);
49 1.1.1.3 mrg c = mpfr_can_round (b, err, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, prec);
50 1.1.1.3 mrg /* If r1 == r2, we can round.
51 1.1.1.3.4.1 christos Note: For r1, RNDF is equivalent to RNDN.
52 1.1.1.3 mrg TODO: complete this test for r1 != r2. */
53 1.1.1.3.4.1 christos if ((r1 == MPFR_RNDF ? MPFR_RNDN : r1) == r2 && !c)
54 1.1.1.3 mrg {
55 1.1.1.3 mrg printf ("Error in test_simple for i=%d,"
56 1.1.1.3 mrg " err=%d r1=%s, r2=%s, p=%d\n", i, err,
57 1.1.1.3 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r1),
58 1.1.1.3 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) r2), p);
59 1.1.1.3 mrg printf ("b="); mpfr_dump (b);
60 1.1.1.3 mrg exit (1);
61 1.1.1.3 mrg }
62 1.1.1.3 mrg mpfr_clear (b);
63 1.1.1.3 mrg }
64 1.1.1.3 mrg }
65 1.1.1.3 mrg
66 1.1 mrg #define MAX_LIMB_SIZE 100
67 1.1 mrg
68 1.1 mrg static void
69 1.1 mrg check_round_p (void)
70 1.1 mrg {
71 1.1 mrg mp_limb_t buf[MAX_LIMB_SIZE];
72 1.1 mrg mp_size_t n, i;
73 1.1 mrg mpfr_prec_t p;
74 1.1 mrg mpfr_exp_t err;
75 1.1 mrg int r1, r2;
76 1.1 mrg
77 1.1 mrg for (n = 2 ; n <= MAX_LIMB_SIZE ; n++)
78 1.1 mrg {
79 1.1 mrg /* avoid mpn_random which leaks memory */
80 1.1 mrg for (i = 0; i < n; i++)
81 1.1 mrg buf[i] = randlimb ();
82 1.1.1.3 mrg /* force the number to be normalized */
83 1.1.1.3 mrg buf[n - 1] |= MPFR_LIMB_HIGHBIT;
84 1.1 mrg p = randlimb() % ((n-1) * GMP_NUMB_BITS) + MPFR_PREC_MIN;
85 1.1 mrg err = p + randlimb () % GMP_NUMB_BITS;
86 1.1 mrg r1 = mpfr_round_p (buf, n, err, p);
87 1.1 mrg r2 = mpfr_can_round_raw (buf, n, MPFR_SIGN_POS, err,
88 1.1 mrg MPFR_RNDN, MPFR_RNDZ, p);
89 1.1 mrg if (r1 != r2)
90 1.1 mrg {
91 1.1 mrg printf ("mpfr_round_p(%d) != mpfr_can_round(%d)!\n"
92 1.1 mrg "bn = %ld, err0 = %ld, prec = %lu\nbp = ",
93 1.1.1.2 mrg r1, r2, n, (long) err, (unsigned long) p);
94 1.1.1.3.4.1 christos #ifndef MPFR_USE_MINI_GMP
95 1.1 mrg gmp_printf ("%NX\n", buf, n);
96 1.1.1.3.4.1 christos #endif
97 1.1 mrg exit (1);
98 1.1 mrg }
99 1.1 mrg }
100 1.1 mrg }
101 1.1 mrg
102 1.1.1.3 mrg /* check x=2^i with precision px, error at most 1, and target precision prec */
103 1.1.1.3 mrg static void
104 1.1.1.3 mrg test_pow2 (mpfr_exp_t i, mpfr_prec_t px, mpfr_rnd_t r1, mpfr_rnd_t r2,
105 1.1.1.3 mrg mpfr_prec_t prec)
106 1.1.1.3 mrg {
107 1.1.1.3 mrg mpfr_t x;
108 1.1.1.3 mrg int b, expected_b, b2;
109 1.1.1.3 mrg
110 1.1.1.3 mrg mpfr_init2 (x, px);
111 1.1.1.3 mrg mpfr_set_ui_2exp (x, 1, i, MPFR_RNDN);
112 1.1.1.3.4.1 christos /* for mpfr_can_round, r1=RNDF is equivalent to r1=RNDN (the sign of the
113 1.1.1.3.4.1 christos error is not known) */
114 1.1.1.3 mrg b = !!mpfr_can_round (x, i+1, r1, r2, prec);
115 1.1.1.3 mrg /* Note: If mpfr_can_round succeeds for both
116 1.1.1.3 mrg (r1,r2) = (MPFR_RNDD,MPFR_RNDN) and
117 1.1.1.3 mrg (r1,r2) = (MPFR_RNDU,MPFR_RNDN), then it should succeed for
118 1.1.1.3 mrg (r1,r2) = (MPFR_RNDN,MPFR_RNDN). So, the condition on prec below
119 1.1.1.3 mrg for r1 = MPFR_RNDN should be the most restrictive between those
120 1.1.1.3 mrg for r1 = any directed rounding mode.
121 1.1.1.3 mrg For r1 like MPFR_RNDA, the unrounded, unknown number may be anyone
122 1.1.1.3 mrg in [2^i-1,i]. As both 2^i-1 and 2^i fit on i bits, one cannot round
123 1.1.1.3 mrg in any precision >= i bits, hence the condition prec < i; prec = i-1
124 1.1.1.3 mrg will work here for r2 = MPFR_RNDN thanks to the even-rounding rule
125 1.1.1.3 mrg (and also with rounding ties away from zero). */
126 1.1.1.3 mrg expected_b =
127 1.1.1.3 mrg MPFR_IS_LIKE_RNDD (r1, MPFR_SIGN_POS) ?
128 1.1.1.3 mrg (MPFR_IS_LIKE_RNDU (r2, MPFR_SIGN_POS) ? 0 : prec <= i) :
129 1.1.1.3 mrg MPFR_IS_LIKE_RNDU (r1, MPFR_SIGN_POS) ?
130 1.1.1.3 mrg (MPFR_IS_LIKE_RNDD (r2, MPFR_SIGN_POS) ? 0 : prec < i) :
131 1.1.1.3 mrg (r2 != MPFR_RNDN ? 0 : prec < i);
132 1.1.1.3 mrg if (b != expected_b)
133 1.1.1.3 mrg {
134 1.1.1.3 mrg printf ("Error for x=2^%d, px=%lu, err=%d, r1=%s, r2=%s, prec=%d\n",
135 1.1.1.3 mrg (int) i, (unsigned long) px, (int) i + 1,
136 1.1.1.3 mrg mpfr_print_rnd_mode (r1), mpfr_print_rnd_mode (r2), (int) prec);
137 1.1.1.3 mrg printf ("Expected %d, got %d\n", expected_b, b);
138 1.1.1.3 mrg exit (1);
139 1.1.1.3 mrg }
140 1.1.1.3 mrg
141 1.1.1.3 mrg if (r1 == MPFR_RNDN && r2 == MPFR_RNDZ)
142 1.1.1.3 mrg {
143 1.1.1.3 mrg /* Similar test to the one done in src/round_p.c
144 1.1.1.3 mrg for MPFR_WANT_ASSERT >= 2. */
145 1.1.1.3 mrg b2 = !!mpfr_round_p (MPFR_MANT(x), MPFR_LIMB_SIZE(x), i+1, prec);
146 1.1.1.3 mrg if (b2 != b)
147 1.1.1.3 mrg {
148 1.1.1.3 mrg printf ("Error for x=2^%d, px=%lu, err=%d, prec=%d\n",
149 1.1.1.3 mrg (int) i, (unsigned long) px, (int) i + 1, (int) prec);
150 1.1.1.3 mrg printf ("mpfr_can_round gave %d, mpfr_round_p gave %d\n", b, b2);
151 1.1.1.3 mrg exit (1);
152 1.1.1.3 mrg }
153 1.1.1.3 mrg }
154 1.1.1.3 mrg
155 1.1.1.3 mrg mpfr_clear (x);
156 1.1.1.3 mrg }
157 1.1.1.3 mrg
158 1.1.1.3 mrg static void
159 1.1.1.3 mrg check_can_round (void)
160 1.1.1.3 mrg {
161 1.1.1.3 mrg mpfr_t x, xinf, xsup, yinf, ysup;
162 1.1.1.3 mrg int precx, precy, err;
163 1.1.1.3 mrg int rnd1, rnd2;
164 1.1.1.3 mrg int i, u[3] = { 0, 1, 256 };
165 1.1.1.3 mrg int inex;
166 1.1.1.3 mrg int expected, got;
167 1.1.1.3 mrg
168 1.1.1.3 mrg mpfr_inits2 (4 * GMP_NUMB_BITS, x, xinf, xsup, yinf, ysup, (mpfr_ptr) 0);
169 1.1.1.3 mrg
170 1.1.1.3 mrg for (precx = 3 * GMP_NUMB_BITS - 3; precx <= 3 * GMP_NUMB_BITS + 3; precx++)
171 1.1.1.3 mrg {
172 1.1.1.3 mrg mpfr_set_prec (x, precx);
173 1.1.1.3 mrg for (precy = precx - 4; precy <= precx + 4; precy++)
174 1.1.1.3 mrg {
175 1.1.1.3 mrg mpfr_set_prec (yinf, precy);
176 1.1.1.3 mrg mpfr_set_prec (ysup, precy);
177 1.1.1.3 mrg
178 1.1.1.3 mrg for (i = 0; i <= 3; i++)
179 1.1.1.3 mrg {
180 1.1.1.3 mrg if (i <= 2)
181 1.1.1.3 mrg {
182 1.1.1.3 mrg /* Test x = 2^(precx - 1) + u */
183 1.1.1.3 mrg mpfr_set_ui_2exp (x, 1, precx - 1, MPFR_RNDN);
184 1.1.1.3 mrg mpfr_add_ui (x, x, u[i], MPFR_RNDN);
185 1.1.1.3 mrg }
186 1.1.1.3 mrg else
187 1.1.1.3 mrg {
188 1.1.1.3 mrg /* Test x = 2^precx - 1 */
189 1.1.1.3 mrg mpfr_set_ui_2exp (x, 1, precx, MPFR_RNDN);
190 1.1.1.3 mrg mpfr_sub_ui (x, x, 1, MPFR_RNDN);
191 1.1.1.3 mrg }
192 1.1.1.3 mrg MPFR_ASSERTN (mpfr_get_exp (x) == precx);
193 1.1.1.3 mrg
194 1.1.1.3 mrg for (err = precy; err <= precy + 3; err++)
195 1.1.1.3 mrg {
196 1.1.1.3 mrg mpfr_set_ui_2exp (xinf, 1, precx - err, MPFR_RNDN);
197 1.1.1.3 mrg inex = mpfr_add (xsup, x, xinf, MPFR_RNDN);
198 1.1.1.3 mrg MPFR_ASSERTN (inex == 0);
199 1.1.1.3 mrg inex = mpfr_sub (xinf, x, xinf, MPFR_RNDN);
200 1.1.1.3 mrg MPFR_ASSERTN (inex == 0);
201 1.1.1.3 mrg RND_LOOP (rnd1)
202 1.1.1.3 mrg RND_LOOP (rnd2)
203 1.1.1.3 mrg {
204 1.1.1.3.4.1 christos if (rnd2 == MPFR_RNDF)
205 1.1.1.3.4.1 christos continue;
206 1.1.1.3 mrg mpfr_set (yinf, MPFR_IS_LIKE_RNDD (rnd1, 1) ?
207 1.1.1.3 mrg x : xinf, (mpfr_rnd_t) rnd2);
208 1.1.1.3 mrg mpfr_set (ysup, MPFR_IS_LIKE_RNDU (rnd1, 1) ?
209 1.1.1.3 mrg x : xsup, (mpfr_rnd_t) rnd2);
210 1.1.1.3 mrg expected = !! mpfr_equal_p (yinf, ysup);
211 1.1.1.3 mrg got = !! mpfr_can_round (x, err, (mpfr_rnd_t) rnd1,
212 1.1.1.3 mrg (mpfr_rnd_t) rnd2, precy);
213 1.1.1.3 mrg if (got != expected)
214 1.1.1.3 mrg {
215 1.1.1.3 mrg printf ("Error in check_can_round on:\n"
216 1.1.1.3 mrg "precx=%d, precy=%d, i=%d, err=%d, "
217 1.1.1.3 mrg "rnd1=%s, rnd2=%s: got %d\n",
218 1.1.1.3 mrg precx, precy, i, err,
219 1.1.1.3 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd1),
220 1.1.1.3 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd2),
221 1.1.1.3 mrg got);
222 1.1.1.3 mrg printf ("x="); mpfr_dump (x);
223 1.1.1.3 mrg exit (1);
224 1.1.1.3 mrg }
225 1.1.1.3 mrg }
226 1.1.1.3 mrg }
227 1.1.1.3 mrg }
228 1.1.1.3 mrg }
229 1.1.1.3 mrg }
230 1.1.1.3 mrg
231 1.1.1.3 mrg mpfr_clears (x, xinf, xsup, yinf, ysup, (mpfr_ptr) 0);
232 1.1.1.3 mrg }
233 1.1.1.3 mrg
234 1.1 mrg int
235 1.1 mrg main (void)
236 1.1 mrg {
237 1.1 mrg mpfr_t x;
238 1.1.1.3 mrg mpfr_prec_t i, j, k;
239 1.1.1.3 mrg int r1, r2;
240 1.1.1.3 mrg int n;
241 1.1 mrg
242 1.1 mrg tests_start_mpfr ();
243 1.1 mrg
244 1.1.1.3 mrg test_simple ();
245 1.1.1.3 mrg
246 1.1 mrg /* checks that rounds to nearest sets the last
247 1.1 mrg bit to zero in case of equal distance */
248 1.1 mrg mpfr_init2 (x, 59);
249 1.1 mrg mpfr_set_str_binary (x, "-0.10010001010111000011110010111010111110000000111101100111111E663");
250 1.1.1.3.4.1 christos if (mpfr_can_round (x, 54, MPFR_RNDZ, MPFR_RNDZ, 53))
251 1.1 mrg {
252 1.1 mrg printf ("Error (1) in mpfr_can_round\n");
253 1.1 mrg exit (1);
254 1.1 mrg }
255 1.1 mrg
256 1.1 mrg mpfr_set_str_binary (x, "-Inf");
257 1.1.1.3.4.1 christos if (mpfr_can_round (x, 2000, MPFR_RNDZ, MPFR_RNDZ, 2000))
258 1.1 mrg {
259 1.1 mrg printf ("Error (2) in mpfr_can_round\n");
260 1.1 mrg exit (1);
261 1.1 mrg }
262 1.1 mrg
263 1.1 mrg mpfr_set_prec (x, 64);
264 1.1 mrg mpfr_set_str_binary (x, "0.1011001000011110000110000110001111101011000010001110011000000000");
265 1.1 mrg if (mpfr_can_round (x, 65, MPFR_RNDN, MPFR_RNDN, 54))
266 1.1 mrg {
267 1.1 mrg printf ("Error (3) in mpfr_can_round\n");
268 1.1 mrg exit (1);
269 1.1 mrg }
270 1.1 mrg
271 1.1 mrg mpfr_set_prec (x, 137);
272 1.1 mrg mpfr_set_str_binary (x, "-0.10111001101001010110011000110100111010011101101010010100101100001110000100111111011101010110001010111100100101110111100001000010000000000E-97");
273 1.1.1.3.4.1 christos if (! mpfr_can_round (x, 132, MPFR_RNDU, MPFR_RNDZ, 128))
274 1.1 mrg {
275 1.1 mrg printf ("Error (4) in mpfr_can_round\n");
276 1.1 mrg exit (1);
277 1.1 mrg }
278 1.1 mrg
279 1.1 mrg /* in the following, we can round but cannot determine the inexact flag */
280 1.1 mrg mpfr_set_prec (x, 86);
281 1.1 mrg mpfr_set_str_binary (x, "-0.11100100010011001111011010100111101010011000000000000000000000000000000000000000000000E-80");
282 1.1.1.3.4.1 christos if (! mpfr_can_round (x, 81, MPFR_RNDU, MPFR_RNDZ, 44))
283 1.1 mrg {
284 1.1 mrg printf ("Error (5) in mpfr_can_round\n");
285 1.1 mrg exit (1);
286 1.1 mrg }
287 1.1 mrg
288 1.1 mrg mpfr_set_prec (x, 62);
289 1.1 mrg mpfr_set_str (x, "0.ff4ca619c76ba69", 16, MPFR_RNDZ);
290 1.1 mrg for (i = 30; i < 99; i++)
291 1.1 mrg for (j = 30; j < 99; j++)
292 1.1.1.3.4.1 christos RND_LOOP (r1)
293 1.1.1.3.4.1 christos RND_LOOP (r2)
294 1.1.1.3.4.1 christos if (r2 != MPFR_RNDF)
295 1.1.1.3.4.1 christos {
296 1.1.1.3.4.1 christos /* test for assertions */
297 1.1.1.3.4.1 christos mpfr_can_round (x, i, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j);
298 1.1.1.3.4.1 christos }
299 1.1.1.3 mrg
300 1.1.1.3 mrg test_pow2 (32, 32, MPFR_RNDN, MPFR_RNDN, 32);
301 1.1.1.3 mrg test_pow2 (174, 174, MPFR_RNDN, MPFR_RNDN, 174);
302 1.1.1.3 mrg test_pow2 (174, 174, MPFR_RNDU, MPFR_RNDN, 174);
303 1.1.1.3 mrg test_pow2 (176, 129, MPFR_RNDU, MPFR_RNDU, 174);
304 1.1.1.3 mrg test_pow2 (176, 2, MPFR_RNDZ, MPFR_RNDZ, 174);
305 1.1.1.3 mrg test_pow2 (176, 2, MPFR_RNDU, MPFR_RNDU, 176);
306 1.1.1.3 mrg
307 1.1.1.3 mrg /* Tests for x = 2^i (E(x) = i+1) with error at most 1 = 2^0. */
308 1.1.1.3 mrg for (n = 0; n < 100; n++)
309 1.1.1.3 mrg {
310 1.1.1.3 mrg i = (randlimb() % 200) + 4;
311 1.1.1.3 mrg for (j = i - 2; j < i + 2; j++)
312 1.1.1.3.4.1 christos RND_LOOP (r1)
313 1.1.1.3.4.1 christos RND_LOOP (r2)
314 1.1.1.3.4.1 christos if (r2 != MPFR_RNDF)
315 1.1.1.3.4.1 christos for (k = MPFR_PREC_MIN; k <= i + 2; k++)
316 1.1.1.3.4.1 christos test_pow2 (i, k, (mpfr_rnd_t) r1, (mpfr_rnd_t) r2, j);
317 1.1.1.3 mrg }
318 1.1 mrg
319 1.1 mrg mpfr_clear (x);
320 1.1 mrg
321 1.1.1.3 mrg check_can_round ();
322 1.1.1.3 mrg
323 1.1 mrg check_round_p ();
324 1.1 mrg
325 1.1 mrg tests_end_mpfr ();
326 1.1 mrg return 0;
327 1.1 mrg }
328