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