Imported Upstream version 3.1.1
[platform/upstream/mpfr.git] / tests / texceptions.c
1 /* Test file for exceptions.
2
3 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel projects, INRIA.
5
6 This file is part of the GNU MPFR Library.
7
8 The GNU MPFR Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
12
13 The GNU MPFR Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
16 License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25
26 #include "mpfr-test.h"
27
28 #define ERROR(s) do { printf(s"\n"); exit(1); } while(0)
29
30 /* Test powerof2 */
31 static void
32 check_powerof2 (void)
33 {
34   mpfr_t x;
35
36   mpfr_init (x);
37   mpfr_set_ui (x, 1, MPFR_RNDN);
38   MPFR_ASSERTN (mpfr_powerof2_raw (x));
39   mpfr_set_ui (x, 3, MPFR_RNDN);
40   MPFR_ASSERTN (!mpfr_powerof2_raw (x));
41   mpfr_clear (x);
42 }
43
44 /* Test default rounding mode */
45 static void
46 check_default_rnd (void)
47 {
48   int r;
49   mpfr_rnd_t t;
50   for(r = 0 ; r < MPFR_RND_MAX ; r++)
51     {
52       mpfr_set_default_rounding_mode ((mpfr_rnd_t) r);
53       t = (mpfr_get_default_rounding_mode) ();
54       if ((mpfr_rnd_t) r != t)
55         {
56           printf ("%s %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) r),
57                   mpfr_print_rnd_mode (t));
58           ERROR("ERROR in setting / getting default rounding mode (1)");
59         }
60     }
61   mpfr_set_default_rounding_mode ((mpfr_rnd_t) MPFR_RND_MAX);
62   if (mpfr_get_default_rounding_mode() != MPFR_RNDA)
63     ERROR("ERROR in setting / getting default rounding mode (2)");
64   mpfr_set_default_rounding_mode((mpfr_rnd_t) -1);
65   if (mpfr_get_default_rounding_mode() != MPFR_RNDA)
66     ERROR("ERROR in setting / getting default rounding mode (3)");
67 }
68
69 static void
70 check_emin_emax (void)
71 {
72   mpfr_exp_t old_emin, old_emax;
73
74   old_emin = mpfr_get_emin ();
75   old_emax = mpfr_get_emax ();
76
77   /* Check the functions not the macros ! */
78   if ((mpfr_set_emin)(MPFR_EMIN_MIN) != 0)
79     ERROR("set_emin failed!");
80   if ((mpfr_get_emin)() != MPFR_EMIN_MIN)
81     ERROR("get_emin FAILED!");
82   if ((mpfr_set_emin)(MPFR_EMIN_MIN-1) == 0)
83     ERROR("set_emin failed! (2)");
84
85   if ((mpfr_set_emax)(MPFR_EMAX_MAX) != 0)
86     ERROR("set_emax failed!");
87   if ((mpfr_get_emax)() != MPFR_EMAX_MAX)
88     ERROR("get_emax FAILED!");
89   if ((mpfr_set_emax)(MPFR_EMAX_MAX+1) == 0)
90     ERROR("set_emax failed! (2)");
91
92   if ((mpfr_get_emin_min) () != MPFR_EMIN_MIN)
93     ERROR ("get_emin_min");
94   if ((mpfr_get_emin_max) () != MPFR_EMIN_MAX)
95     ERROR ("get_emin_max");
96   if ((mpfr_get_emax_min) () != MPFR_EMAX_MIN)
97     ERROR ("get_emax_min");
98   if ((mpfr_get_emax_max) () != MPFR_EMAX_MAX)
99     ERROR ("get_emax_max");
100
101   set_emin (old_emin);
102   set_emax (old_emax);
103 }
104
105 static void
106 check_set_get_prec (void)
107 {
108   mpfr_t x;
109
110   mpfr_init2 (x, 17);
111   if (mpfr_get_prec (x) != 17 || (mpfr_get_prec)(x) != 17)
112     ERROR ("mpfr_get_prec");
113   mpfr_clear (x);
114 }
115
116 static void
117 mpfr_set_double_range (void)
118 {
119   mpfr_set_default_prec (54);
120   if (mpfr_get_default_prec () != 54)
121     ERROR ("get_default_prec failed (1)");
122   mpfr_set_default_prec (53);
123   if ((mpfr_get_default_prec) () != 53)
124     ERROR ("get_default_prec failed (2)");
125
126   /* in double precision format, the unbiased exponent is between 0 and
127      2047, where 0 is used for subnormal numbers, and 2047 for special
128      numbers (infinities, NaN), and the bias is 1023, thus "normal" numbers
129      have an exponent between -1022 and 1023, corresponding to numbers
130      between 2^(-1022) and previous(2^(1024)).
131      (The smallest subnormal number is 0.(0^51)1*2^(-1022)= 2^(-1074).)
132
133      The smallest normal power of two is 1.0*2^(-1022).
134      The largest normal power of two is 2^1023.
135      (We have to add one for mpfr since mantissa are between 1/2 and 1.)
136   */
137
138   set_emin (-1021);
139   set_emax (1024);
140 }
141
142 static void
143 check_flags (void)
144 {
145   mpfr_t x;
146   mpfr_exp_t old_emin, old_emax;
147
148   old_emin = mpfr_get_emin ();
149   old_emax = mpfr_get_emax ();
150   mpfr_init (x);
151
152   /* Check the functions not the macros ! */
153   (mpfr_clear_flags)();
154   mpfr_set_double_range ();
155
156   mpfr_set_ui (x, 1, MPFR_RNDN);
157   (mpfr_clear_overflow)();
158   mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
159   if (!(mpfr_overflow_p)())
160     ERROR("ERROR: No overflow detected!\n");
161
162   (mpfr_clear_underflow)();
163   mpfr_set_ui (x, 1, MPFR_RNDN);
164   mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
165   if (!(mpfr_underflow_p)())
166     ERROR("ERROR: No underflow detected!\n");
167
168   (mpfr_clear_nanflag)();
169   MPFR_SET_NAN(x);
170   mpfr_add (x, x, x, MPFR_RNDN);
171   if (!(mpfr_nanflag_p)())
172     ERROR("ERROR: No NaN flag!\n");
173
174   (mpfr_clear_inexflag)();
175   mpfr_set_ui(x, 2, MPFR_RNDN);
176   mpfr_cos(x, x, MPFR_RNDN);
177   if (!(mpfr_inexflag_p)())
178     ERROR("ERROR: No inexact flag!\n");
179
180   (mpfr_clear_erangeflag) ();
181   mpfr_set_ui (x, 1, MPFR_RNDN);
182   mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
183   mpfr_get_ui (x, MPFR_RNDN);
184   if (!(mpfr_erangeflag_p)())
185     ERROR ("ERROR: No erange flag!\n");
186
187   mpfr_clear (x);
188   set_emin (old_emin);
189   set_emax (old_emax);
190 }
191
192 static void
193 test_set_underflow (void)
194 {
195   mpfr_t x, zero, min;
196   mpfr_ptr r[MPFR_RND_MAX];
197   int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */
198   int i;
199   int s;
200
201   mpfr_inits (x, zero, min, (mpfr_ptr) 0);
202   mpfr_set_ui (zero, 0, MPFR_RNDN);
203   mpfr_set_ui (min, 0, MPFR_RNDN);
204   mpfr_nextabove (min);
205   r[0] = r[2] = r[4] = min; /* RNDN, RNDU, RNDA */
206   r[1] = r[3] = zero;       /* RNDZ, RNDD */
207   for (s = 1; s > 0; s = -1)
208     {
209       for (i = 0; i < MPFR_RND_MAX ; i++)
210         {
211           int j;
212           int inex;
213
214           j = s < 0 && i > 1 ? 5 - i : i;
215           inex = mpfr_underflow (x, (mpfr_rnd_t) i, s);
216           if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0)
217             {
218               printf ("Error in test_set_underflow, sign = %d,"
219                       " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
220               printf ("Got\n");
221               mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
222               printf (", inex = %d\ninstead of\n", inex);
223               mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN);
224               printf (", inex = %d\n", t[j]);
225               exit (1);
226             }
227         }
228       mpfr_neg (zero, zero, MPFR_RNDN);
229       mpfr_neg (min, min, MPFR_RNDN);
230     }
231   mpfr_clears (x, zero, min, (mpfr_ptr) 0);
232 }
233
234 static void
235 test_set_overflow (void)
236 {
237   mpfr_t x, inf, max;
238   mpfr_ptr r[MPFR_RND_MAX];
239   int t[MPFR_RND_MAX] = { 1, -1, 1, -1, 1 }; /* RNDN, RNDZ, RNDU, RNDD, RNDA */
240   int i;
241   int s;
242
243   mpfr_inits2 (32, x, inf, max, (mpfr_ptr) 0);
244   mpfr_set_inf (inf, 1);
245   mpfr_set_inf (max, 1);
246   mpfr_nextbelow (max);
247   r[0] = r[2] = r[4] = inf; /* RNDN, RNDU, RNDA */
248   r[1] = r[3] = max;        /* RNDZ, RNDD */
249   for (s = 1; s > 0; s = -1)
250     {
251       for (i = 0; i < MPFR_RND_MAX ; i++)
252         {
253           int j;
254           int inex;
255
256           j = s < 0 && i > 1 ? 5 - i : i;
257           inex = mpfr_overflow (x, (mpfr_rnd_t) i, s);
258           if (mpfr_cmp (x, r[j]) || inex * t[j] <= 0)
259             {
260               printf ("Error in test_set_overflow, sign = %d,"
261                       " rnd_mode = %s\n", s, mpfr_print_rnd_mode ((mpfr_rnd_t) i));
262               printf ("Got\n");
263               mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN);
264               printf (", inex = %d\ninstead of\n", inex);
265               mpfr_out_str (stdout, 2, 0, r[j], MPFR_RNDN);
266               printf (", inex = %d\n", t[j]);
267               exit (1);
268             }
269         }
270       mpfr_neg (inf, inf, MPFR_RNDN);
271       mpfr_neg (max, max, MPFR_RNDN);
272     }
273   mpfr_clears (x, inf, max, (mpfr_ptr) 0);
274 }
275
276 static void
277 check_set (void)
278 {
279   mpfr_clear_flags ();
280
281   mpfr_set_overflow ();
282   MPFR_ASSERTN ((mpfr_overflow_p) ());
283   mpfr_set_underflow ();
284   MPFR_ASSERTN ((mpfr_underflow_p) ());
285   mpfr_set_divby0 ();
286   MPFR_ASSERTN ((mpfr_divby0_p) ());
287   mpfr_set_nanflag ();
288   MPFR_ASSERTN ((mpfr_nanflag_p) ());
289   mpfr_set_inexflag ();
290   MPFR_ASSERTN ((mpfr_inexflag_p) ());
291   mpfr_set_erangeflag ();
292   MPFR_ASSERTN ((mpfr_erangeflag_p) ());
293
294   MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL);
295
296   mpfr_clear_overflow ();
297   MPFR_ASSERTN (! (mpfr_overflow_p) ());
298   mpfr_clear_underflow ();
299   MPFR_ASSERTN (! (mpfr_underflow_p) ());
300   mpfr_clear_divby0 ();
301   MPFR_ASSERTN (! (mpfr_divby0_p) ());
302   mpfr_clear_nanflag ();
303   MPFR_ASSERTN (! (mpfr_nanflag_p) ());
304   mpfr_clear_inexflag ();
305   MPFR_ASSERTN (! (mpfr_inexflag_p) ());
306   mpfr_clear_erangeflag ();
307   MPFR_ASSERTN (! (mpfr_erangeflag_p) ());
308
309   MPFR_ASSERTN (__gmpfr_flags == 0);
310
311   (mpfr_set_overflow) ();
312   MPFR_ASSERTN (mpfr_overflow_p ());
313   (mpfr_set_underflow) ();
314   MPFR_ASSERTN (mpfr_underflow_p ());
315   (mpfr_set_divby0) ();
316   MPFR_ASSERTN (mpfr_divby0_p ());
317   (mpfr_set_nanflag) ();
318   MPFR_ASSERTN (mpfr_nanflag_p ());
319   (mpfr_set_inexflag) ();
320   MPFR_ASSERTN (mpfr_inexflag_p ());
321   (mpfr_set_erangeflag) ();
322   MPFR_ASSERTN (mpfr_erangeflag_p ());
323
324   MPFR_ASSERTN (__gmpfr_flags == MPFR_FLAGS_ALL);
325
326   (mpfr_clear_overflow) ();
327   MPFR_ASSERTN (! mpfr_overflow_p ());
328   (mpfr_clear_underflow) ();
329   MPFR_ASSERTN (! mpfr_underflow_p ());
330   (mpfr_clear_divby0) ();
331   MPFR_ASSERTN (! mpfr_divby0_p ());
332   (mpfr_clear_nanflag) ();
333   MPFR_ASSERTN (! mpfr_nanflag_p ());
334   (mpfr_clear_inexflag) ();
335   MPFR_ASSERTN (! mpfr_inexflag_p ());
336   (mpfr_clear_erangeflag) ();
337   MPFR_ASSERTN (! mpfr_erangeflag_p ());
338
339   MPFR_ASSERTN (__gmpfr_flags == 0);
340 }
341
342 int
343 main (int argc, char *argv[])
344 {
345   mpfr_t x, y;
346   mpfr_exp_t emin, emax;
347
348   tests_start_mpfr ();
349
350   test_set_underflow ();
351   test_set_overflow ();
352   check_default_rnd();
353
354   mpfr_init (x);
355   mpfr_init (y);
356
357   emin = mpfr_get_emin ();
358   emax = mpfr_get_emax ();
359   if (emin >= emax)
360     {
361       printf ("Error: emin >= emax\n");
362       exit (1);
363     }
364
365   mpfr_set_ui (x, 1, MPFR_RNDN);
366   mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
367   mpfr_set_double_range ();
368   mpfr_check_range (x, 0, MPFR_RNDN);
369   if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
370     {
371       printf ("Error: 2^1024 rounded to nearest should give +Inf\n");
372       exit (1);
373     }
374
375   set_emax (1025);
376   mpfr_set_ui (x, 1, MPFR_RNDN);
377   mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
378   mpfr_set_double_range ();
379   mpfr_check_range (x, 0, MPFR_RNDD);
380   if (!mpfr_number_p (x))
381     {
382       printf ("Error: 2^1024 rounded down should give a normal number\n");
383       exit (1);
384     }
385
386   mpfr_set_ui (x, 1, MPFR_RNDN);
387   mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
388   mpfr_add (x, x, x, MPFR_RNDN);
389   if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
390     {
391       printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n");
392       printf ("emax = %ld\n", (long) mpfr_get_emax ());
393       printf ("got "); mpfr_print_binary (x); puts ("");
394       exit (1);
395     }
396
397   mpfr_set_ui (x, 1, MPFR_RNDN);
398   mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
399   mpfr_add (x, x, x, MPFR_RNDD);
400   if (!mpfr_number_p (x))
401     {
402       printf ("Error: x+x rounded down for x=2^1023 should give"
403               " a normal number\n");
404       exit (1);
405     }
406
407   mpfr_set_ui (x, 1, MPFR_RNDN);
408   mpfr_div_2exp (x, x, 1022, MPFR_RNDN);
409   mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */
410   mpfr_sub (y, y, x, MPFR_RNDZ);
411   if (mpfr_cmp_ui (y, 0))
412     {
413       printf ("Error: y-x rounded to zero should give 0"
414               " for y=3/2*2^(-1022), x=2^(-1022)\n");
415       printf ("y="); mpfr_print_binary (y); puts ("");
416       exit (1);
417     }
418
419   set_emin (-1026);
420   mpfr_set_ui (x, 1, MPFR_RNDN);
421   mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
422   mpfr_set_double_range ();
423   mpfr_check_range (x, 0, MPFR_RNDN);
424   if (!MPFR_IS_ZERO (x) )
425     {
426       printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n");
427       printf ("emin = %ld\n", (long) mpfr_get_emin ());
428       printf ("got "); mpfr_dump (x);
429       exit (1);
430     }
431
432   mpfr_clear (x);
433   mpfr_clear (y);
434
435   set_emin (emin);
436   set_emax (emax);
437
438   check_emin_emax();
439   check_flags();
440   check_set_get_prec ();
441   check_powerof2 ();
442   check_set ();
443
444   tests_end_mpfr ();
445   return 0;
446 }