texp.c revision 1.2 1 1.1 mrg /* Test file for mpfr_exp.
2 1.1 mrg
3 1.1 mrg Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 1.1 mrg Contributed by the Arenaire and Cacao 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 <stdio.h>
24 1.1 mrg #include <stdlib.h>
25 1.1 mrg #include <limits.h>
26 1.1 mrg
27 1.1 mrg #include "mpfr-test.h"
28 1.1 mrg
29 1.1 mrg #ifdef CHECK_EXTERNAL
30 1.1 mrg static int
31 1.1 mrg test_exp (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode)
32 1.1 mrg {
33 1.1 mrg int res;
34 1.1 mrg int ok = rnd_mode == MPFR_RNDN && mpfr_number_p (b) && mpfr_get_prec (a)>=53;
35 1.1 mrg if (ok)
36 1.1 mrg {
37 1.1 mrg mpfr_print_raw (b);
38 1.1 mrg }
39 1.1 mrg res = mpfr_exp (a, b, rnd_mode);
40 1.1 mrg if (ok)
41 1.1 mrg {
42 1.1 mrg printf (" ");
43 1.1 mrg mpfr_print_raw (a);
44 1.1 mrg printf ("\n");
45 1.1 mrg }
46 1.1 mrg return res;
47 1.1 mrg }
48 1.1 mrg #else
49 1.1 mrg #define test_exp mpfr_exp
50 1.1 mrg #endif
51 1.1 mrg
52 1.1 mrg /* returns the number of ulp of error */
53 1.1 mrg static void
54 1.1 mrg check3 (const char *op, mpfr_rnd_t rnd, const char *res)
55 1.1 mrg {
56 1.1 mrg mpfr_t x, y;
57 1.1 mrg
58 1.1 mrg mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
59 1.1 mrg /* y negative. If we forget to set the sign in mpfr_exp, we'll see it. */
60 1.1 mrg mpfr_set_si (y, -1, MPFR_RNDN);
61 1.1 mrg mpfr_set_str1 (x, op);
62 1.1 mrg test_exp (y, x, rnd);
63 1.1 mrg if (mpfr_cmp_str1 (y, res) )
64 1.1 mrg {
65 1.1 mrg printf ("mpfr_exp failed for x=%s, rnd=%s\n",
66 1.1 mrg op, mpfr_print_rnd_mode (rnd));
67 1.1 mrg printf ("expected result is %s, got ", res);
68 1.1 mrg mpfr_out_str (stdout, 10, 0, y, MPFR_RNDN);
69 1.1 mrg putchar('\n');
70 1.1 mrg exit (1);
71 1.1 mrg }
72 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0);
73 1.1 mrg }
74 1.1 mrg
75 1.1 mrg /* expx is the value of exp(X) rounded toward -infinity */
76 1.1 mrg static void
77 1.1 mrg check_worst_case (const char *Xs, const char *expxs)
78 1.1 mrg {
79 1.1 mrg mpfr_t x, y;
80 1.1 mrg
81 1.1 mrg mpfr_inits2 (53, x, y, (mpfr_ptr) 0);
82 1.1 mrg mpfr_set_str1(x, Xs);
83 1.1 mrg test_exp(y, x, MPFR_RNDD);
84 1.1 mrg if (mpfr_cmp_str1 (y, expxs))
85 1.1 mrg {
86 1.1 mrg printf ("exp(x) rounded toward -infinity is wrong\n");
87 1.1 mrg exit(1);
88 1.1 mrg }
89 1.1 mrg mpfr_set_str1(x, Xs);
90 1.1 mrg test_exp(x, x, MPFR_RNDU);
91 1.1 mrg mpfr_nexttoinf (y);
92 1.1 mrg if (mpfr_cmp(x,y))
93 1.1 mrg {
94 1.1 mrg printf ("exp(x) rounded toward +infinity is wrong\n");
95 1.1 mrg exit(1);
96 1.1 mrg }
97 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0);
98 1.1 mrg }
99 1.1 mrg
100 1.1 mrg /* worst cases communicated by Jean-Michel Muller and Vincent Lefevre */
101 1.1 mrg static int
102 1.1 mrg check_worst_cases (void)
103 1.1 mrg {
104 1.1 mrg mpfr_t x; mpfr_t y;
105 1.1 mrg
106 1.1 mrg mpfr_init(x);
107 1.1 mrg mpfr_set_prec (x, 53);
108 1.1 mrg
109 1.1 mrg check_worst_case("4.44089209850062517562e-16", "1.00000000000000022204");
110 1.1 mrg check_worst_case("6.39488462184069720009e-14", "1.00000000000006372680");
111 1.1 mrg check_worst_case("1.84741111297455401935e-12", "1.00000000000184718907");
112 1.1 mrg check_worst_case("1.76177628026265550074e-10", "1.00000000017617751702");
113 1.1 mrg check3("1.76177628026265550074e-10", MPFR_RNDN, "1.00000000017617773906");
114 1.1 mrg check_worst_case("7.54175277499595900852e-10", "1.00000000075417516676");
115 1.1 mrg check3("7.54175277499595900852e-10", MPFR_RNDN, "1.00000000075417538881");
116 1.1 mrg /* bug found by Vincent Lefe`vre on December 8, 1999 */
117 1.1 mrg check3("-5.42410311287441459172e+02", MPFR_RNDN, "2.7176584868845723e-236");
118 1.1 mrg /* further cases communicated by Vincent Lefe`vre on January 27, 2000 */
119 1.1 mrg check3("-1.32920285897904911589e-10", MPFR_RNDN, "0.999999999867079769622");
120 1.1 mrg check3("-1.44037948245738330735e-10", MPFR_RNDN, "0.9999999998559621072757");
121 1.1 mrg check3("-1.66795910430705305937e-10", MPFR_RNDZ, "0.9999999998332040895832");
122 1.1 mrg check3("-1.64310953745426656203e-10", MPFR_RNDN, "0.9999999998356891017792");
123 1.1 mrg check3("-1.38323574826034659172e-10", MPFR_RNDZ, "0.9999999998616764251835");
124 1.1 mrg check3("-1.23621668465115401498e-10", MPFR_RNDZ, "0.9999999998763783315425");
125 1.1 mrg
126 1.1 mrg mpfr_set_prec (x, 601);
127 1.1 mrg mpfr_set_str (x, "0.88b6ba510e10450edc258748bc9dfdd466f21b47ed264cdf24aa8f64af1f3fad9ec2301d43c0743f534b5aa20091ff6d352df458ef1ba519811ef6f5b11853534fd8fa32764a0a6d2d0dd20@0", 16, MPFR_RNDZ);
128 1.1 mrg mpfr_init2 (y, 601);
129 1.1 mrg mpfr_exp_2 (y, x, MPFR_RNDD);
130 1.1 mrg mpfr_exp_3 (x, x, MPFR_RNDD);
131 1.1 mrg if (mpfr_cmp (x, y))
132 1.1 mrg {
133 1.1 mrg printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=601\n");
134 1.1 mrg printf ("mpfr_exp_2 gives ");
135 1.1 mrg mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
136 1.1 mrg printf ("\nmpfr_exp_3 gives ");
137 1.1 mrg mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
138 1.1 mrg printf ("\n");
139 1.1 mrg exit (1);
140 1.1 mrg }
141 1.1 mrg
142 1.1 mrg mpfr_set_prec (x, 13001);
143 1.1 mrg mpfr_set_prec (y, 13001);
144 1.1 mrg mpfr_urandomb (x, RANDS);
145 1.1 mrg mpfr_exp_3 (y, x, MPFR_RNDN);
146 1.1 mrg mpfr_exp_2 (x, x, MPFR_RNDN);
147 1.1 mrg if (mpfr_cmp (x, y))
148 1.1 mrg {
149 1.1 mrg printf ("mpfr_exp_2 and mpfr_exp_3 differ for prec=13001\n");
150 1.1 mrg exit (1);
151 1.1 mrg }
152 1.1 mrg
153 1.1 mrg mpfr_clear (x);
154 1.1 mrg mpfr_clear (y);
155 1.1 mrg return 0;
156 1.1 mrg }
157 1.1 mrg
158 1.1 mrg static void
159 1.1 mrg compare_exp2_exp3 (mpfr_prec_t p0, mpfr_prec_t p1)
160 1.1 mrg {
161 1.1 mrg mpfr_t x, y, z;
162 1.1 mrg mpfr_prec_t prec;
163 1.1 mrg mpfr_rnd_t rnd;
164 1.1 mrg
165 1.1 mrg mpfr_init (x);
166 1.1 mrg mpfr_init (y);
167 1.1 mrg mpfr_init (z);
168 1.1 mrg for (prec = p0; prec <= p1; prec ++)
169 1.1 mrg {
170 1.1 mrg mpfr_set_prec (x, prec);
171 1.1 mrg mpfr_set_prec (y, prec);
172 1.1 mrg mpfr_set_prec (z, prec);
173 1.2 drochner do
174 1.2 drochner mpfr_urandomb (x, RANDS);
175 1.2 drochner while (MPFR_IS_ZERO (x)); /* 0 is handled by mpfr_exp only */
176 1.1 mrg rnd = RND_RAND ();
177 1.1 mrg mpfr_exp_2 (y, x, rnd);
178 1.1 mrg mpfr_exp_3 (z, x, rnd);
179 1.1 mrg if (mpfr_cmp (y,z))
180 1.1 mrg {
181 1.1 mrg printf ("mpfr_exp_2 and mpfr_exp_3 disagree for rnd=%s and\nx=",
182 1.1 mrg mpfr_print_rnd_mode (rnd));
183 1.1 mrg mpfr_print_binary (x);
184 1.1 mrg puts ("");
185 1.1 mrg printf ("mpfr_exp_2 gives ");
186 1.1 mrg mpfr_print_binary (y);
187 1.1 mrg puts ("");
188 1.1 mrg printf ("mpfr_exp_3 gives ");
189 1.1 mrg mpfr_print_binary (z);
190 1.1 mrg puts ("");
191 1.1 mrg exit (1);
192 1.1 mrg }
193 1.1 mrg }
194 1.1 mrg
195 1.1 mrg mpfr_clear (x);
196 1.1 mrg mpfr_clear (y);
197 1.1 mrg mpfr_clear (z);
198 1.1 mrg }
199 1.1 mrg
200 1.1 mrg static void
201 1.1 mrg check_large (void)
202 1.1 mrg {
203 1.1 mrg mpfr_t x, z;
204 1.1 mrg mpfr_prec_t prec;
205 1.1 mrg
206 1.1 mrg /* bug found by Patrick Pe'lissier on 7 Jun 2004 */
207 1.1 mrg prec = 203780;
208 1.1 mrg mpfr_init2 (x, prec);
209 1.1 mrg mpfr_init2 (z, prec);
210 1.1 mrg mpfr_set_ui (x, 3, MPFR_RNDN);
211 1.1 mrg mpfr_sqrt (x, x, MPFR_RNDN);
212 1.1 mrg mpfr_sub_ui (x, x, 1, MPFR_RNDN);
213 1.1 mrg mpfr_exp_3 (z, x, MPFR_RNDN);
214 1.1 mrg mpfr_clear (x);
215 1.1 mrg mpfr_clear (z);
216 1.1 mrg }
217 1.1 mrg
218 1.1 mrg #define TEST_FUNCTION test_exp
219 1.1 mrg #define TEST_RANDOM_EMIN -36
220 1.1 mrg #define TEST_RANDOM_EMAX 36
221 1.1 mrg #include "tgeneric.c"
222 1.1 mrg
223 1.1 mrg static void
224 1.1 mrg check_special (void)
225 1.1 mrg {
226 1.1 mrg mpfr_t x, y, z;
227 1.1 mrg mpfr_exp_t emin, emax;
228 1.1 mrg
229 1.1 mrg emin = mpfr_get_emin ();
230 1.1 mrg emax = mpfr_get_emax ();
231 1.1 mrg
232 1.1 mrg mpfr_init (x);
233 1.1 mrg mpfr_init (y);
234 1.1 mrg mpfr_init (z);
235 1.1 mrg
236 1.1 mrg /* check exp(NaN) = NaN */
237 1.1 mrg mpfr_set_nan (x);
238 1.1 mrg test_exp (y, x, MPFR_RNDN);
239 1.1 mrg if (!mpfr_nan_p (y))
240 1.1 mrg {
241 1.1 mrg printf ("Error for exp(NaN)\n");
242 1.1 mrg exit (1);
243 1.1 mrg }
244 1.1 mrg
245 1.1 mrg /* check exp(+inf) = +inf */
246 1.1 mrg mpfr_set_inf (x, 1);
247 1.1 mrg test_exp (y, x, MPFR_RNDN);
248 1.1 mrg if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
249 1.1 mrg {
250 1.1 mrg printf ("Error for exp(+inf)\n");
251 1.1 mrg exit (1);
252 1.1 mrg }
253 1.1 mrg
254 1.1 mrg /* check exp(-inf) = +0 */
255 1.1 mrg mpfr_set_inf (x, -1);
256 1.1 mrg test_exp (y, x, MPFR_RNDN);
257 1.1 mrg if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
258 1.1 mrg {
259 1.1 mrg printf ("Error for exp(-inf)\n");
260 1.1 mrg exit (1);
261 1.1 mrg }
262 1.1 mrg
263 1.1 mrg /* Check overflow. Corner case of mpfr_exp_2 */
264 1.1 mrg mpfr_set_prec (x, 64);
265 1.1 mrg mpfr_set_emax (MPFR_EMAX_DEFAULT);
266 1.1 mrg mpfr_set_emin (MPFR_EMIN_DEFAULT);
267 1.1 mrg mpfr_set_str (x,
268 1.1 mrg "0.1011000101110010000101111111010100001100000001110001100111001101E30",
269 1.1 mrg 2, MPFR_RNDN);
270 1.1 mrg mpfr_exp (x, x, MPFR_RNDD);
271 1.1 mrg if (mpfr_cmp_str (x,
272 1.1 mrg ".1111111111111111111111111111111111111111111111111111111111111111E1073741823",
273 1.1 mrg 2, MPFR_RNDN) != 0)
274 1.1 mrg {
275 1.1 mrg printf ("Wrong overflow detection in mpfr_exp\n");
276 1.1 mrg mpfr_dump (x);
277 1.1 mrg exit (1);
278 1.1 mrg }
279 1.1 mrg /* Check underflow. Corner case of mpfr_exp_2 */
280 1.1 mrg mpfr_set_str (x,
281 1.1 mrg "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
282 1.1 mrg 2, MPFR_RNDN);
283 1.1 mrg mpfr_exp (x, x, MPFR_RNDN);
284 1.1 mrg if (mpfr_cmp_str (x, "0.1E-1073741823", 2, MPFR_RNDN) != 0)
285 1.1 mrg {
286 1.1 mrg printf ("Wrong underflow (1) detection in mpfr_exp\n");
287 1.1 mrg mpfr_dump (x);
288 1.1 mrg exit (1);
289 1.1 mrg }
290 1.1 mrg mpfr_set_str (x,
291 1.1 mrg "-0.1011001101110010000101111111011111010001110011110111100110111101E30",
292 1.1 mrg 2, MPFR_RNDN);
293 1.1 mrg mpfr_exp (x, x, MPFR_RNDN);
294 1.1 mrg if (mpfr_cmp_ui (x, 0) != 0)
295 1.1 mrg {
296 1.1 mrg printf ("Wrong underflow (2) detection in mpfr_exp\n");
297 1.1 mrg mpfr_dump (x);
298 1.1 mrg exit (1);
299 1.1 mrg }
300 1.1 mrg /* Check overflow. Corner case of mpfr_exp_3 */
301 1.1 mrg if (MPFR_PREC_MAX >= MPFR_EXP_THRESHOLD + 10 && MPFR_PREC_MAX >= 64)
302 1.1 mrg {
303 1.1 mrg /* this ensures that for small MPFR_EXP_THRESHOLD, the following
304 1.1 mrg mpfr_set_str conversion is exact */
305 1.1 mrg mpfr_set_prec (x, (MPFR_EXP_THRESHOLD + 10 > 64)
306 1.1 mrg ? MPFR_EXP_THRESHOLD + 10 : 64);
307 1.1 mrg mpfr_set_str (x,
308 1.1 mrg "0.1011000101110010000101111111010100001100000001110001100111001101E30",
309 1.1 mrg 2, MPFR_RNDN);
310 1.1 mrg mpfr_clear_overflow ();
311 1.1 mrg mpfr_exp (x, x, MPFR_RNDD);
312 1.1 mrg if (!mpfr_overflow_p ())
313 1.1 mrg {
314 1.1 mrg printf ("Wrong overflow detection in mpfr_exp_3\n");
315 1.1 mrg mpfr_dump (x);
316 1.1 mrg exit (1);
317 1.1 mrg }
318 1.1 mrg /* Check underflow. Corner case of mpfr_exp_3 */
319 1.1 mrg mpfr_set_str (x,
320 1.1 mrg "-0.1011000101110010000101111111011111010001110011110111100110101100E30",
321 1.1 mrg 2, MPFR_RNDN);
322 1.1 mrg mpfr_clear_underflow ();
323 1.1 mrg mpfr_exp (x, x, MPFR_RNDN);
324 1.1 mrg if (!mpfr_underflow_p ())
325 1.1 mrg {
326 1.1 mrg printf ("Wrong underflow detection in mpfr_exp_3\n");
327 1.1 mrg mpfr_dump (x);
328 1.1 mrg exit (1);
329 1.1 mrg }
330 1.1 mrg mpfr_set_prec (x, 53);
331 1.1 mrg }
332 1.1 mrg
333 1.1 mrg /* check overflow */
334 1.1 mrg set_emax (10);
335 1.1 mrg mpfr_set_ui (x, 7, MPFR_RNDN);
336 1.1 mrg test_exp (y, x, MPFR_RNDN);
337 1.1 mrg if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0)
338 1.1 mrg {
339 1.1 mrg printf ("Error for exp(7) for emax=10\n");
340 1.1 mrg exit (1);
341 1.1 mrg }
342 1.1 mrg set_emax (emax);
343 1.1 mrg
344 1.1 mrg /* check underflow */
345 1.1 mrg set_emin (-10);
346 1.1 mrg mpfr_set_si (x, -9, MPFR_RNDN);
347 1.1 mrg test_exp (y, x, MPFR_RNDN);
348 1.1 mrg if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0)
349 1.1 mrg {
350 1.1 mrg printf ("Error for exp(-9) for emin=-10\n");
351 1.1 mrg printf ("Expected +0\n");
352 1.1 mrg printf ("Got "); mpfr_print_binary (y); puts ("");
353 1.1 mrg exit (1);
354 1.1 mrg }
355 1.1 mrg set_emin (emin);
356 1.1 mrg
357 1.1 mrg /* check case EXP(x) < -precy */
358 1.1 mrg mpfr_set_prec (y, 2);
359 1.1 mrg mpfr_set_str_binary (x, "-0.1E-3");
360 1.1 mrg test_exp (y, x, MPFR_RNDD);
361 1.1 mrg if (mpfr_cmp_ui_2exp (y, 3, -2))
362 1.1 mrg {
363 1.1 mrg printf ("Error for exp(-1/16), prec=2, RNDD\n");
364 1.1 mrg printf ("expected 0.11, got ");
365 1.1 mrg mpfr_dump (y);
366 1.1 mrg exit (1);
367 1.1 mrg }
368 1.1 mrg test_exp (y, x, MPFR_RNDZ);
369 1.1 mrg if (mpfr_cmp_ui_2exp (y, 3, -2))
370 1.1 mrg {
371 1.1 mrg printf ("Error for exp(-1/16), prec=2, RNDZ\n");
372 1.1 mrg printf ("expected 0.11, got ");
373 1.1 mrg mpfr_dump (y);
374 1.1 mrg exit (1);
375 1.1 mrg }
376 1.1 mrg mpfr_set_str_binary (x, "0.1E-3");
377 1.1 mrg test_exp (y, x, MPFR_RNDN);
378 1.1 mrg if (mpfr_cmp_ui (y, 1))
379 1.1 mrg {
380 1.1 mrg printf ("Error for exp(1/16), prec=2, RNDN\n");
381 1.1 mrg exit (1);
382 1.1 mrg }
383 1.1 mrg test_exp (y, x, MPFR_RNDU);
384 1.1 mrg if (mpfr_cmp_ui_2exp (y, 3, -1))
385 1.1 mrg {
386 1.1 mrg printf ("Error for exp(1/16), prec=2, RNDU\n");
387 1.1 mrg exit (1);
388 1.1 mrg }
389 1.1 mrg
390 1.1 mrg /* bug reported by Franky Backeljauw, 28 Mar 2003 */
391 1.1 mrg mpfr_set_prec (x, 53);
392 1.1 mrg mpfr_set_prec (y, 53);
393 1.1 mrg mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
394 1.1 mrg test_exp (y, x, MPFR_RNDN);
395 1.1 mrg
396 1.1 mrg mpfr_set_prec (x, 153);
397 1.1 mrg mpfr_set_prec (z, 153);
398 1.1 mrg mpfr_set_str_binary (x, "1.1101011000111101011110000111010010101001101001110111e28");
399 1.1 mrg test_exp (z, x, MPFR_RNDN);
400 1.1 mrg mpfr_prec_round (z, 53, MPFR_RNDN);
401 1.1 mrg
402 1.1 mrg if (mpfr_cmp (y, z))
403 1.1 mrg {
404 1.1 mrg printf ("Error in mpfr_exp for large argument\n");
405 1.1 mrg exit (1);
406 1.1 mrg }
407 1.1 mrg
408 1.1 mrg /* corner cases in mpfr_exp_3 */
409 1.1 mrg mpfr_set_prec (x, 2);
410 1.1 mrg mpfr_set_ui (x, 1, MPFR_RNDN);
411 1.1 mrg mpfr_set_prec (y, 2);
412 1.1 mrg mpfr_exp_3 (y, x, MPFR_RNDN);
413 1.1 mrg
414 1.1 mrg /* Check some little things about overflow detection */
415 1.1 mrg set_emin (-125);
416 1.1 mrg set_emax (128);
417 1.1 mrg mpfr_set_prec (x, 107);
418 1.1 mrg mpfr_set_prec (y, 107);
419 1.1 mrg mpfr_set_str_binary (x, "0.11110000000000000000000000000000000000000000000"
420 1.1 mrg "0000000000000000000000000000000000000000000000000000"
421 1.1 mrg "00000000E4");
422 1.1 mrg test_exp (y, x, MPFR_RNDN);
423 1.1 mrg if (mpfr_cmp_str (y, "0.11000111100001100110010101111101011010010101010000"
424 1.1 mrg "1101110111100010111001011111111000110111001011001101010"
425 1.1 mrg "01E22", 2, MPFR_RNDN))
426 1.1 mrg {
427 1.1 mrg printf ("Special overflow error (1)\n");
428 1.1 mrg mpfr_dump (y);
429 1.1 mrg exit (1);
430 1.1 mrg }
431 1.1 mrg
432 1.1 mrg set_emin (emin);
433 1.1 mrg set_emax (emax);
434 1.1 mrg
435 1.1 mrg /* Check for overflow producing a segfault with HUGE exponent */
436 1.1 mrg mpfr_set_ui (x, 3, MPFR_RNDN);
437 1.1 mrg mpfr_mul_2ui (x, x, 32, MPFR_RNDN);
438 1.1 mrg test_exp (y, x, MPFR_RNDN); /* Can't test return value: May overflow or not*/
439 1.1 mrg
440 1.1 mrg /* Bug due to wrong approximation of (x)/log2 */
441 1.1 mrg mpfr_set_prec (x, 163);
442 1.1 mrg
443 1.1 mrg mpfr_set_str (x, "-4.28ac8fceeadcda06bb56359017b1c81b85b392e7", 16,
444 1.1 mrg MPFR_RNDN);
445 1.1 mrg mpfr_exp (x, x, MPFR_RNDN);
446 1.1 mrg if (mpfr_cmp_str (x, "3.fffffffffffffffffffffffffffffffffffffffe8@-2",
447 1.1 mrg 16, MPFR_RNDN))
448 1.1 mrg {
449 1.1 mrg printf ("Error for x= -4.28ac8fceeadcda06bb56359017b1c81b85b392e7");
450 1.1 mrg printf ("expected 3.fffffffffffffffffffffffffffffffffffffffe8@-2");
451 1.1 mrg printf ("Got ");
452 1.1 mrg mpfr_out_str (stdout, 16, 0, x, MPFR_RNDN); putchar ('\n');
453 1.1 mrg }
454 1.1 mrg
455 1.1 mrg /* bug found by Guillaume Melquiond, 13 Sep 2005 */
456 1.1 mrg mpfr_set_prec (x, 53);
457 1.1 mrg mpfr_set_str_binary (x, "-1E-400");
458 1.1 mrg mpfr_exp (x, x, MPFR_RNDZ);
459 1.1 mrg if (mpfr_cmp_ui (x, 1) == 0)
460 1.1 mrg {
461 1.1 mrg printf ("Error for exp(-2^(-400))\n");
462 1.1 mrg exit (1);
463 1.1 mrg }
464 1.1 mrg
465 1.1 mrg mpfr_clear (x);
466 1.1 mrg mpfr_clear (y);
467 1.1 mrg mpfr_clear (z);
468 1.1 mrg }
469 1.1 mrg
470 1.1 mrg /* check sign of inexact flag */
471 1.1 mrg static void
472 1.1 mrg check_inexact (void)
473 1.1 mrg {
474 1.1 mrg mpfr_t x, y;
475 1.1 mrg int inexact;
476 1.1 mrg
477 1.1 mrg mpfr_init2 (x, 53);
478 1.1 mrg mpfr_init2 (y, 53);
479 1.1 mrg
480 1.1 mrg mpfr_set_str_binary (x,
481 1.1 mrg "1.0000000000001001000110100100101000001101101011100101e2");
482 1.1 mrg inexact = test_exp (y, x, MPFR_RNDN);
483 1.1 mrg if (inexact <= 0)
484 1.1 mrg {
485 1.1 mrg printf ("Wrong inexact flag (Got %d instead of 1)\n", inexact);
486 1.1 mrg exit (1);
487 1.1 mrg }
488 1.1 mrg
489 1.1 mrg mpfr_clear (x);
490 1.1 mrg mpfr_clear (y);
491 1.1 mrg }
492 1.1 mrg
493 1.1 mrg static void
494 1.1 mrg check_exp10(void)
495 1.1 mrg {
496 1.1 mrg mpfr_t x;
497 1.1 mrg int inexact;
498 1.1 mrg
499 1.1 mrg mpfr_init2 (x, 200);
500 1.1 mrg mpfr_set_ui(x, 4, MPFR_RNDN);
501 1.1 mrg
502 1.1 mrg inexact = mpfr_exp10 (x, x, MPFR_RNDN);
503 1.1 mrg if (mpfr_cmp_ui(x, 10*10*10*10))
504 1.1 mrg {
505 1.1 mrg printf ("exp10: Wrong returned value\n");
506 1.1 mrg exit (1);
507 1.1 mrg }
508 1.1 mrg if (inexact != 0)
509 1.1 mrg {
510 1.1 mrg printf ("exp10: Wrong inexact flag\n");
511 1.1 mrg exit (1);
512 1.1 mrg }
513 1.1 mrg
514 1.1 mrg mpfr_clear (x);
515 1.1 mrg }
516 1.1 mrg
517 1.1 mrg static void
518 1.1 mrg overflowed_exp0 (void)
519 1.1 mrg {
520 1.1 mrg mpfr_t x, y;
521 1.1 mrg int emax, i, inex, rnd, err = 0;
522 1.1 mrg mpfr_exp_t old_emax;
523 1.1 mrg
524 1.1 mrg old_emax = mpfr_get_emax ();
525 1.1 mrg
526 1.1 mrg mpfr_init2 (x, 8);
527 1.1 mrg mpfr_init2 (y, 8);
528 1.1 mrg
529 1.1 mrg for (emax = -1; emax <= 0; emax++)
530 1.1 mrg {
531 1.1 mrg mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN);
532 1.1 mrg mpfr_nextbelow (y);
533 1.1 mrg set_emax (emax); /* 1 is not representable. */
534 1.1 mrg /* and if emax < 0, 1 - eps is not representable either. */
535 1.1 mrg for (i = -1; i <= 1; i++)
536 1.1 mrg RND_LOOP (rnd)
537 1.1 mrg {
538 1.1 mrg mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN);
539 1.1 mrg mpfr_clear_flags ();
540 1.1 mrg inex = mpfr_exp (x, x, (mpfr_rnd_t) rnd);
541 1.1 mrg if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) &&
542 1.1 mrg ! mpfr_overflow_p ())
543 1.1 mrg {
544 1.1 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
545 1.1 mrg " The overflow flag is not set.\n",
546 1.1 mrg i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
547 1.1 mrg err = 1;
548 1.1 mrg }
549 1.1 mrg if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD)
550 1.1 mrg {
551 1.1 mrg if (inex >= 0)
552 1.1 mrg {
553 1.1 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
554 1.1 mrg " The inexact value must be negative.\n",
555 1.1 mrg i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
556 1.1 mrg err = 1;
557 1.1 mrg }
558 1.1 mrg if (! mpfr_equal_p (x, y))
559 1.1 mrg {
560 1.1 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
561 1.1 mrg " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
562 1.1 mrg mpfr_print_binary (x);
563 1.1 mrg printf (" instead of 0.11111111E%d.\n", emax);
564 1.1 mrg err = 1;
565 1.1 mrg }
566 1.1 mrg }
567 1.1 mrg else
568 1.1 mrg {
569 1.1 mrg if (inex <= 0)
570 1.1 mrg {
571 1.1 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
572 1.1 mrg " The inexact value must be positive.\n",
573 1.1 mrg i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
574 1.1 mrg err = 1;
575 1.1 mrg }
576 1.1 mrg if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0))
577 1.1 mrg {
578 1.1 mrg printf ("Error in overflowed_exp0 (i = %d, rnd = %s):\n"
579 1.1 mrg " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
580 1.1 mrg mpfr_print_binary (x);
581 1.1 mrg printf (" instead of +Inf.\n");
582 1.1 mrg err = 1;
583 1.1 mrg }
584 1.1 mrg }
585 1.1 mrg }
586 1.1 mrg set_emax (old_emax);
587 1.1 mrg }
588 1.1 mrg
589 1.1 mrg if (err)
590 1.1 mrg exit (1);
591 1.1 mrg mpfr_clear (x);
592 1.1 mrg mpfr_clear (y);
593 1.1 mrg }
594 1.1 mrg
595 1.1 mrg /* This bug occurs in mpfr_exp_2 on a Linux-64 machine, r5475. */
596 1.1 mrg static void
597 1.1 mrg bug20080731 (void)
598 1.1 mrg {
599 1.1 mrg mpfr_exp_t emin;
600 1.1 mrg mpfr_t x, y1, y2;
601 1.1 mrg mpfr_prec_t prec = 64;
602 1.1 mrg
603 1.1 mrg emin = mpfr_get_emin ();
604 1.1 mrg set_emin (MPFR_EMIN_MIN);
605 1.1 mrg
606 1.1 mrg mpfr_init2 (x, 200);
607 1.1 mrg mpfr_set_str (x, "-2.c5c85fdf473de6af278ece700fcbdabd03cd0cb9ca62d8b62c@7",
608 1.1 mrg 16, MPFR_RNDN);
609 1.1 mrg
610 1.1 mrg mpfr_init2 (y1, prec);
611 1.1 mrg mpfr_exp (y1, x, MPFR_RNDU);
612 1.1 mrg
613 1.1 mrg /* Compute the result with a higher internal precision. */
614 1.1 mrg mpfr_init2 (y2, 300);
615 1.1 mrg mpfr_exp (y2, x, MPFR_RNDU);
616 1.1 mrg mpfr_prec_round (y2, prec, MPFR_RNDU);
617 1.1 mrg
618 1.1 mrg if (mpfr_cmp0 (y1, y2) != 0)
619 1.1 mrg {
620 1.1 mrg printf ("Error in bug20080731\nExpected ");
621 1.1 mrg mpfr_out_str (stdout, 16, 0, y2, MPFR_RNDN);
622 1.1 mrg printf ("\nGot ");
623 1.1 mrg mpfr_out_str (stdout, 16, 0, y1, MPFR_RNDN);
624 1.1 mrg printf ("\n");
625 1.1 mrg exit (1);
626 1.1 mrg }
627 1.1 mrg
628 1.1 mrg mpfr_clears (x, y1, y2, (mpfr_ptr) 0);
629 1.1 mrg set_emin (emin);
630 1.1 mrg }
631 1.1 mrg
632 1.1 mrg /* Emulate mpfr_exp with mpfr_exp_3 in the general case. */
633 1.1 mrg static int
634 1.1 mrg exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode)
635 1.1 mrg {
636 1.1 mrg int inexact;
637 1.1 mrg
638 1.1 mrg inexact = mpfr_exp_3 (y, x, rnd_mode);
639 1.1 mrg return mpfr_check_range (y, inexact, rnd_mode);
640 1.1 mrg }
641 1.1 mrg
642 1.1 mrg static void
643 1.1 mrg underflow_up (int extended_emin)
644 1.1 mrg {
645 1.1 mrg mpfr_t minpos, x, y, t, t2;
646 1.1 mrg int precx, precy;
647 1.1 mrg int inex;
648 1.1 mrg int rnd;
649 1.1 mrg int e3;
650 1.1 mrg int i, j;
651 1.1 mrg
652 1.1 mrg mpfr_init2 (minpos, 2);
653 1.1 mrg mpfr_set_ui (minpos, 0, MPFR_RNDN);
654 1.1 mrg mpfr_nextabove (minpos);
655 1.1 mrg
656 1.1 mrg /* Let's test values near the underflow boundary.
657 1.1 mrg *
658 1.1 mrg * Minimum representable positive number: minpos = 2^(emin - 1).
659 1.1 mrg * Let's choose an MPFR number x = log(minpos) + eps, with |eps| small
660 1.1 mrg * (note: eps cannot be 0, and cannot be a rational number either).
661 1.1 mrg * Then exp(x) = minpos * exp(eps) ~= minpos * (1 + eps + eps^2).
662 1.1 mrg * We will compute y = rnd(exp(x)) in some rounding mode, precision p.
663 1.1 mrg * 1. If eps > 0, then in any rounding mode:
664 1.1 mrg * rnd(exp(x)) >= minpos and no underflow.
665 1.1 mrg * So, let's take x1 = rndu(log(minpos)) in some precision.
666 1.1 mrg * 2. If eps < 0, then exp(x) < minpos and the result will be either 0
667 1.1 mrg * or minpos. An underflow always occurs in MPFR_RNDZ and MPFR_RNDD,
668 1.1 mrg * but not necessarily in MPFR_RNDN and MPFR_RNDU (this is underflow
669 1.1 mrg * after rounding in an unbounded exponent range). If -a < eps < -b,
670 1.1 mrg * minpos * (1 - a) < exp(x) < minpos * (1 - b + b^2).
671 1.1 mrg * - If eps > -2^(-p), no underflow in MPFR_RNDU.
672 1.1 mrg * - If eps > -2^(-p-1), no underflow in MPFR_RNDN.
673 1.1 mrg * - If eps < - (2^(-p-1) + 2^(-2p-1)), underflow in MPFR_RNDN.
674 1.1 mrg * - If eps < - (2^(-p) + 2^(-2p+1)), underflow in MPFR_RNDU.
675 1.1 mrg * - In MPFR_RNDN, result is minpos iff exp(eps) > 1/2, i.e.
676 1.1 mrg * - log(2) < eps < ...
677 1.1 mrg *
678 1.1 mrg * Moreover, since precy < MPFR_EXP_THRESHOLD (to avoid tests that take
679 1.1 mrg * too much time), mpfr_exp() always selects mpfr_exp_2(); so, we need
680 1.1 mrg * to test mpfr_exp_3() too. This will be done via the e3 variable:
681 1.1 mrg * e3 = 0: mpfr_exp(), thus mpfr_exp_2().
682 1.1 mrg * e3 = 1: mpfr_exp_3(), via the exp_3() wrapper.
683 1.1 mrg * i.e.: inex = e3 ? exp_3 (y, x, rnd) : mpfr_exp (y, x, rnd);
684 1.1 mrg */
685 1.1 mrg
686 1.1 mrg /* Case eps > 0. In revision 5461 (trunk) on a 64-bit Linux machine:
687 1.1 mrg * Incorrect flags in underflow_up, eps > 0, MPFR_RNDN and extended emin
688 1.1 mrg * for precx = 96, precy = 16, mpfr_exp_3
689 1.1 mrg * Got 9 instead of 8.
690 1.1 mrg * Note: testing this case in several precisions for x and y introduces
691 1.1 mrg * some useful random. Indeed, the bug is not always triggered.
692 1.1 mrg * Fixed in r5469.
693 1.1 mrg */
694 1.1 mrg for (precx = 16; precx <= 128; precx += 16)
695 1.1 mrg {
696 1.1 mrg mpfr_init2 (x, precx);
697 1.1 mrg mpfr_log (x, minpos, MPFR_RNDU);
698 1.1 mrg for (precy = 16; precy <= 128; precy += 16)
699 1.1 mrg {
700 1.1 mrg mpfr_init2 (y, precy);
701 1.1 mrg
702 1.1 mrg for (e3 = 0; e3 <= 1; e3++)
703 1.1 mrg {
704 1.1 mrg RND_LOOP (rnd)
705 1.1 mrg {
706 1.1 mrg int err = 0;
707 1.1 mrg
708 1.1 mrg mpfr_clear_flags ();
709 1.1 mrg inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
710 1.1 mrg : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
711 1.1 mrg if (__gmpfr_flags != MPFR_FLAGS_INEXACT)
712 1.1 mrg {
713 1.1 mrg printf ("Incorrect flags in underflow_up, eps > 0, %s",
714 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
715 1.1 mrg if (extended_emin)
716 1.1 mrg printf (" and extended emin");
717 1.1 mrg printf ("\nfor precx = %d, precy = %d, %s\n",
718 1.1 mrg precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
719 1.1 mrg printf ("Got %u instead of %u.\n", __gmpfr_flags,
720 1.1 mrg (unsigned int) MPFR_FLAGS_INEXACT);
721 1.1 mrg err = 1;
722 1.1 mrg }
723 1.1 mrg if (mpfr_cmp0 (y, minpos) < 0)
724 1.1 mrg {
725 1.1 mrg printf ("Incorrect result in underflow_up, eps > 0, %s",
726 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
727 1.1 mrg if (extended_emin)
728 1.1 mrg printf (" and extended emin");
729 1.1 mrg printf ("\nfor precx = %d, precy = %d, %s\n",
730 1.1 mrg precx, precy, e3 ? "mpfr_exp_3" : "mpfr_exp");
731 1.1 mrg mpfr_dump (y);
732 1.1 mrg err = 1;
733 1.1 mrg }
734 1.1 mrg MPFR_ASSERTN (inex != 0);
735 1.1 mrg if (rnd == MPFR_RNDD || rnd == MPFR_RNDZ)
736 1.1 mrg MPFR_ASSERTN (inex < 0);
737 1.1 mrg if (rnd == MPFR_RNDU)
738 1.1 mrg MPFR_ASSERTN (inex > 0);
739 1.1 mrg if (err)
740 1.1 mrg exit (1);
741 1.1 mrg }
742 1.1 mrg }
743 1.1 mrg
744 1.1 mrg mpfr_clear (y);
745 1.1 mrg }
746 1.1 mrg mpfr_clear (x);
747 1.1 mrg }
748 1.1 mrg
749 1.1 mrg /* Case - log(2) < eps < 0 in MPFR_RNDN, starting with small-precision x;
750 1.1 mrg * only check the result and the ternary value.
751 1.1 mrg * Previous to r5453 (trunk), on 32-bit and 64-bit machines, this fails
752 1.1 mrg * for precx = 65 and precy = 16, e.g.:
753 1.1 mrg * exp_2.c:264: assertion failed: ...
754 1.1 mrg * because mpfr_sub (r, x, r, MPFR_RNDU); yields a null value. This is
755 1.1 mrg * fixed in r5453 by going to next Ziv's iteration.
756 1.1 mrg */
757 1.1 mrg for (precx = sizeof(mpfr_exp_t) * CHAR_BIT + 1; precx <= 81; precx += 8)
758 1.1 mrg {
759 1.1 mrg mpfr_init2 (x, precx);
760 1.1 mrg mpfr_log (x, minpos, MPFR_RNDD); /* |ulp| <= 1/2 */
761 1.1 mrg for (precy = 16; precy <= 128; precy += 16)
762 1.1 mrg {
763 1.1 mrg mpfr_init2 (y, precy);
764 1.1 mrg inex = mpfr_exp (y, x, MPFR_RNDN);
765 1.1 mrg if (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
766 1.1 mrg {
767 1.1 mrg printf ("Error in underflow_up, - log(2) < eps < 0");
768 1.1 mrg if (extended_emin)
769 1.1 mrg printf (" and extended emin");
770 1.1 mrg printf (" for prec = %d\nExpected ", precy);
771 1.1 mrg mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
772 1.1 mrg printf (" (minimum positive MPFR number) and inex > 0\nGot ");
773 1.1 mrg mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
774 1.1 mrg printf ("\nwith inex = %d\n", inex);
775 1.1 mrg exit (1);
776 1.1 mrg }
777 1.1 mrg mpfr_clear (y);
778 1.1 mrg }
779 1.1 mrg mpfr_clear (x);
780 1.1 mrg }
781 1.1 mrg
782 1.1 mrg /* Cases eps ~ -2^(-p) and eps ~ -2^(-p-1). More precisely,
783 1.1 mrg * _ for j = 0, eps > -2^(-(p+i)),
784 1.1 mrg * _ for j = 1, eps < - (2^(-(p+i)) + 2^(1-2(p+i))),
785 1.1 mrg * where i = 0 or 1.
786 1.1 mrg */
787 1.1 mrg mpfr_inits2 (2, t, t2, (mpfr_ptr) 0);
788 1.1 mrg for (precy = 16; precy <= 128; precy += 16)
789 1.1 mrg {
790 1.1 mrg mpfr_set_ui_2exp (t, 1, - precy, MPFR_RNDN); /* 2^(-p) */
791 1.1 mrg mpfr_set_ui_2exp (t2, 1, 1 - 2 * precy, MPFR_RNDN); /* 2^(-2p+1) */
792 1.1 mrg precx = sizeof(mpfr_exp_t) * CHAR_BIT + 2 * precy + 8;
793 1.1 mrg mpfr_init2 (x, precx);
794 1.1 mrg mpfr_init2 (y, precy);
795 1.1 mrg for (i = 0; i <= 1; i++)
796 1.1 mrg {
797 1.1 mrg for (j = 0; j <= 1; j++)
798 1.1 mrg {
799 1.1 mrg if (j == 0)
800 1.1 mrg {
801 1.1 mrg /* Case eps > -2^(-(p+i)). */
802 1.1 mrg mpfr_log (x, minpos, MPFR_RNDU);
803 1.1 mrg }
804 1.1 mrg else /* j == 1 */
805 1.1 mrg {
806 1.1 mrg /* Case eps < - (2^(-(p+i)) + 2^(1-2(p+i))). */
807 1.1 mrg mpfr_log (x, minpos, MPFR_RNDD);
808 1.1 mrg inex = mpfr_sub (x, x, t2, MPFR_RNDN);
809 1.1 mrg MPFR_ASSERTN (inex == 0);
810 1.1 mrg }
811 1.1 mrg inex = mpfr_sub (x, x, t, MPFR_RNDN);
812 1.1 mrg MPFR_ASSERTN (inex == 0);
813 1.1 mrg
814 1.1 mrg RND_LOOP (rnd)
815 1.1 mrg for (e3 = 0; e3 <= 1; e3++)
816 1.1 mrg {
817 1.1 mrg int err = 0;
818 1.1 mrg unsigned int flags;
819 1.1 mrg
820 1.1 mrg flags = MPFR_FLAGS_INEXACT |
821 1.1 mrg (((rnd == MPFR_RNDU || rnd == MPFR_RNDA)
822 1.1 mrg && (i == 1 || j == 0)) ||
823 1.1 mrg (rnd == MPFR_RNDN && (i == 1 && j == 0)) ?
824 1.1 mrg 0 : MPFR_FLAGS_UNDERFLOW);
825 1.1 mrg mpfr_clear_flags ();
826 1.1 mrg inex = e3 ? exp_3 (y, x, (mpfr_rnd_t) rnd)
827 1.1 mrg : mpfr_exp (y, x, (mpfr_rnd_t) rnd);
828 1.1 mrg if (__gmpfr_flags != flags)
829 1.1 mrg {
830 1.1 mrg printf ("Incorrect flags in underflow_up, %s",
831 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
832 1.1 mrg if (extended_emin)
833 1.1 mrg printf (" and extended emin");
834 1.1 mrg printf ("\nfor precx = %d, precy = %d, ",
835 1.1 mrg precx, precy);
836 1.1 mrg if (j == 0)
837 1.1 mrg printf ("eps >~ -2^(-%d)", precy + i);
838 1.1 mrg else
839 1.1 mrg printf ("eps <~ - (2^(-%d) + 2^(%d))",
840 1.1 mrg precy + i, 1 - 2 * (precy + i));
841 1.1 mrg printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
842 1.1 mrg printf ("Got %u instead of %u.\n",
843 1.1 mrg __gmpfr_flags, flags);
844 1.1 mrg err = 1;
845 1.1 mrg }
846 1.1 mrg if (rnd == MPFR_RNDU || rnd == MPFR_RNDA || rnd == MPFR_RNDN ?
847 1.1 mrg mpfr_cmp0 (y, minpos) != 0 : MPFR_NOTZERO (y))
848 1.1 mrg {
849 1.1 mrg printf ("Incorrect result in underflow_up, %s",
850 1.1 mrg mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
851 1.1 mrg if (extended_emin)
852 1.1 mrg printf (" and extended emin");
853 1.1 mrg printf ("\nfor precx = %d, precy = %d, ",
854 1.1 mrg precx, precy);
855 1.1 mrg if (j == 0)
856 1.1 mrg printf ("eps >~ -2^(-%d)", precy + i);
857 1.1 mrg else
858 1.1 mrg printf ("eps <~ - (2^(-%d) + 2^(%d))",
859 1.1 mrg precy + i, 1 - 2 * (precy + i));
860 1.1 mrg printf (", %s\n", e3 ? "mpfr_exp_3" : "mpfr_exp");
861 1.1 mrg mpfr_dump (y);
862 1.1 mrg err = 1;
863 1.1 mrg }
864 1.1 mrg if (err)
865 1.1 mrg exit (1);
866 1.1 mrg } /* for (e3 ...) */
867 1.1 mrg } /* for (j ...) */
868 1.1 mrg mpfr_div_2si (t, t, 1, MPFR_RNDN);
869 1.1 mrg mpfr_div_2si (t2, t2, 2, MPFR_RNDN);
870 1.1 mrg } /* for (i ...) */
871 1.1 mrg mpfr_clears (x, y, (mpfr_ptr) 0);
872 1.1 mrg } /* for (precy ...) */
873 1.1 mrg mpfr_clears (t, t2, (mpfr_ptr) 0);
874 1.1 mrg
875 1.1 mrg /* Case exp(eps) ~= 1/2, i.e. eps ~= - log(2).
876 1.1 mrg * We choose x0 and x1 with high enough precision such that:
877 1.1 mrg * x0 = rndd(rndd(log(minpos)) - rndu(log(2)))
878 1.1 mrg * x1 = rndu(rndu(log(minpos)) - rndd(log(2)))
879 1.1 mrg * In revision 5507 (trunk) on a 64-bit Linux machine, this fails:
880 1.1 mrg * Error in underflow_up, eps >~ - log(2) and extended emin
881 1.1 mrg * for precy = 16, mpfr_exp
882 1.1 mrg * Expected 1.0@-1152921504606846976 (minimum positive MPFR number),
883 1.1 mrg * inex > 0 and flags = 9
884 1.1 mrg * Got 0
885 1.1 mrg * with inex = -1 and flags = 9
886 1.1 mrg * due to a double-rounding problem in mpfr_mul_2si when rescaling
887 1.1 mrg * the result.
888 1.1 mrg */
889 1.1 mrg mpfr_inits2 (sizeof(mpfr_exp_t) * CHAR_BIT + 64, x, t, (mpfr_ptr) 0);
890 1.1 mrg for (i = 0; i <= 1; i++)
891 1.1 mrg {
892 1.1 mrg mpfr_log (x, minpos, i ? MPFR_RNDU : MPFR_RNDD);
893 1.1 mrg mpfr_const_log2 (t, i ? MPFR_RNDD : MPFR_RNDU);
894 1.1 mrg mpfr_sub (x, x, t, i ? MPFR_RNDU : MPFR_RNDD);
895 1.1 mrg for (precy = 16; precy <= 128; precy += 16)
896 1.1 mrg {
897 1.1 mrg mpfr_init2 (y, precy);
898 1.1 mrg for (e3 = 0; e3 <= 1; e3++)
899 1.1 mrg {
900 1.1 mrg unsigned int flags, uflags =
901 1.1 mrg MPFR_FLAGS_INEXACT | MPFR_FLAGS_UNDERFLOW;
902 1.1 mrg
903 1.1 mrg mpfr_clear_flags ();
904 1.1 mrg inex = e3 ? exp_3 (y, x, MPFR_RNDN) : mpfr_exp (y, x, MPFR_RNDN);
905 1.1 mrg flags = __gmpfr_flags;
906 1.1 mrg if (flags != uflags ||
907 1.1 mrg (i ? (inex <= 0 || mpfr_cmp0 (y, minpos) != 0)
908 1.1 mrg : (inex >= 0 || MPFR_NOTZERO (y))))
909 1.1 mrg {
910 1.1 mrg printf ("Error in underflow_up, eps %c~ - log(2)",
911 1.1 mrg i ? '>' : '<');
912 1.1 mrg if (extended_emin)
913 1.1 mrg printf (" and extended emin");
914 1.1 mrg printf ("\nfor precy = %d, %s\nExpected ", precy,
915 1.1 mrg e3 ? "mpfr_exp_3" : "mpfr_exp");
916 1.1 mrg if (i)
917 1.1 mrg {
918 1.1 mrg mpfr_out_str (stdout, 16, 0, minpos, MPFR_RNDN);
919 1.1 mrg printf (" (minimum positive MPFR number),\ninex >");
920 1.1 mrg }
921 1.1 mrg else
922 1.1 mrg {
923 1.1 mrg printf ("+0, inex <");
924 1.1 mrg }
925 1.1 mrg printf (" 0 and flags = %u\nGot ", uflags);
926 1.1 mrg mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN);
927 1.1 mrg printf ("\nwith inex = %d and flags = %u\n", inex, flags);
928 1.1 mrg exit (1);
929 1.1 mrg }
930 1.1 mrg }
931 1.1 mrg mpfr_clear (y);
932 1.1 mrg }
933 1.1 mrg }
934 1.1 mrg mpfr_clears (x, t, (mpfr_ptr) 0);
935 1.1 mrg
936 1.1 mrg mpfr_clear (minpos);
937 1.1 mrg }
938 1.1 mrg
939 1.1 mrg static void
940 1.1 mrg underflow (void)
941 1.1 mrg {
942 1.1 mrg mpfr_exp_t emin;
943 1.1 mrg
944 1.1 mrg underflow_up (0);
945 1.1 mrg
946 1.1 mrg emin = mpfr_get_emin ();
947 1.1 mrg set_emin (MPFR_EMIN_MIN);
948 1.1 mrg if (mpfr_get_emin () != emin)
949 1.1 mrg {
950 1.1 mrg underflow_up (1);
951 1.1 mrg set_emin (emin);
952 1.1 mrg }
953 1.1 mrg }
954 1.1 mrg
955 1.1 mrg int
956 1.1 mrg main (int argc, char *argv[])
957 1.1 mrg {
958 1.1 mrg tests_start_mpfr ();
959 1.1 mrg
960 1.1 mrg if (argc > 1)
961 1.1 mrg check_large ();
962 1.1 mrg
963 1.1 mrg check_inexact ();
964 1.1 mrg check_special ();
965 1.1 mrg
966 1.1 mrg test_generic (2, 100, 100);
967 1.1 mrg
968 1.1 mrg compare_exp2_exp3 (20, 1000);
969 1.1 mrg check_worst_cases();
970 1.1 mrg check3("0.0", MPFR_RNDU, "1.0");
971 1.1 mrg check3("-1e-170", MPFR_RNDU, "1.0");
972 1.1 mrg check3("-1e-170", MPFR_RNDN, "1.0");
973 1.1 mrg check3("-8.88024741073346941839e-17", MPFR_RNDU, "1.0");
974 1.1 mrg check3("8.70772839244701057915e-01", MPFR_RNDN, "2.38875626491680437269");
975 1.1 mrg check3("1.0", MPFR_RNDN, "2.71828182845904509080");
976 1.1 mrg check3("-3.42135637628104173534e-07", MPFR_RNDZ, "0.999999657864420798958");
977 1.1 mrg /* worst case for argument reduction, very near from 5*log(2),
978 1.1 mrg thanks to Jean-Michel Muller */
979 1.1 mrg check3("3.4657359027997265421", MPFR_RNDN, "32.0");
980 1.1 mrg check3("3.4657359027997265421", MPFR_RNDU, "32.0");
981 1.1 mrg check3("3.4657359027997265421", MPFR_RNDD, "31.999999999999996447");
982 1.1 mrg check3("2.26523754332090625496e+01", MPFR_RNDD, "6.8833785261699581146e9");
983 1.1 mrg check3("1.31478962104089092122e+01", MPFR_RNDZ, "5.12930793917860137299e+05");
984 1.1 mrg check3("4.25637507920002378103e-01", MPFR_RNDU, "1.53056585656161181497e+00");
985 1.1 mrg check3("6.26551618962329307459e-16", MPFR_RNDU, "1.00000000000000066613e+00");
986 1.1 mrg check3("-3.35589513871216568383e-03",MPFR_RNDD, "9.96649729583626853291e-01");
987 1.1 mrg check3("1.95151388850007272424e+01", MPFR_RNDU, "2.98756340674767792225e+08");
988 1.1 mrg check3("2.45045953503350730784e+01", MPFR_RNDN, "4.38743344916128387451e+10");
989 1.1 mrg check3("2.58165606081678085104e+01", MPFR_RNDD, "1.62925781879432281494e+11");
990 1.1 mrg check3("-2.36539020084338638128e+01",MPFR_RNDZ, "5.33630792749924762447e-11");
991 1.1 mrg check3("2.39211946135858077866e+01", MPFR_RNDU, "2.44817704330214385986e+10");
992 1.1 mrg check3("-2.78190533055889162029e+01",MPFR_RNDZ, "8.2858803483596879512e-13");
993 1.1 mrg check3("2.64028186174889789584e+01", MPFR_RNDD, "2.9281844652878973388e11");
994 1.1 mrg check3("2.92086338843268329413e+01", MPFR_RNDZ, "4.8433797301907177734e12");
995 1.1 mrg check3("-2.46355324071459982349e+01",MPFR_RNDZ, "1.9995129297760994791e-11");
996 1.1 mrg check3("-2.23509444608605427618e+01",MPFR_RNDZ, "1.9638492867489702307e-10");
997 1.1 mrg check3("-2.41175390197331687148e+01",MPFR_RNDD, "3.3564940885530624592e-11");
998 1.1 mrg check3("2.46363885231578088053e+01", MPFR_RNDU, "5.0055014282693267822e10");
999 1.1 mrg check3("111.1263531080090984914932050742208957672119140625", MPFR_RNDN, "1.8262572323517295459e48");
1000 1.1 mrg check3("-3.56196340354684821250e+02",MPFR_RNDN, "2.0225297096141478156e-155");
1001 1.1 mrg check3("6.59678273772710895173e+02", MPFR_RNDU, "3.1234469273830195529e286");
1002 1.1 mrg check3("5.13772529701934331570e+02", MPFR_RNDD, "1.3445427121297197752e223");
1003 1.1 mrg check3("3.57430211008718345056e+02", MPFR_RNDD, "1.6981197246857298443e155");
1004 1.1 mrg check3("3.82001814471465536371e+02", MPFR_RNDU, "7.9667300591087367805e165");
1005 1.1 mrg check3("5.92396038219384422518e+02", MPFR_RNDD, "1.880747529554661989e257");
1006 1.1 mrg check3("-5.02678550462488090034e+02",MPFR_RNDU, "4.8919201895446217839e-219");
1007 1.1 mrg check3("5.30015757134837031117e+02", MPFR_RNDD, "1.5237672861171573939e230");
1008 1.1 mrg check3("5.16239362447650933063e+02", MPFR_RNDZ, "1.5845518406744492105e224");
1009 1.1 mrg check3("6.00812634798592370977e-01", MPFR_RNDN, "1.823600119339019443");
1010 1.1 mrg check_exp10 ();
1011 1.1 mrg
1012 1.1 mrg bug20080731 ();
1013 1.1 mrg
1014 1.1 mrg overflowed_exp0 ();
1015 1.1 mrg underflow ();
1016 1.1 mrg
1017 1.1 mrg data_check ("data/exp", mpfr_exp, "mpfr_exp");
1018 1.1 mrg bad_cases (mpfr_exp, mpfr_log, "mpfr_exp", 0, -256, 255, 4, 128, 800, 50);
1019 1.1 mrg
1020 1.1 mrg tests_end_mpfr ();
1021 1.1 mrg return 0;
1022 1.1 mrg }
1023