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