xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/texceptions.c (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /* Test file for exceptions.
2 
3 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao 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_nanflag ();
286   MPFR_ASSERTN ((mpfr_nanflag_p) ());
287   mpfr_set_inexflag ();
288   MPFR_ASSERTN ((mpfr_inexflag_p) ());
289   mpfr_set_erangeflag ();
290   MPFR_ASSERTN ((mpfr_erangeflag_p) ());
291 
292   mpfr_clear_flags ();
293 }
294 
295 int
296 main (int argc, char *argv[])
297 {
298   mpfr_t x, y;
299   mpfr_exp_t emin, emax;
300 
301   tests_start_mpfr ();
302 
303   test_set_underflow ();
304   test_set_overflow ();
305   check_default_rnd();
306 
307   mpfr_init (x);
308   mpfr_init (y);
309 
310   emin = mpfr_get_emin ();
311   emax = mpfr_get_emax ();
312   if (emin >= emax)
313     {
314       printf ("Error: emin >= emax\n");
315       exit (1);
316     }
317 
318   mpfr_set_ui (x, 1, MPFR_RNDN);
319   mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
320   mpfr_set_double_range ();
321   mpfr_check_range (x, 0, MPFR_RNDN);
322   if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
323     {
324       printf ("Error: 2^1024 rounded to nearest should give +Inf\n");
325       exit (1);
326     }
327 
328   set_emax (1025);
329   mpfr_set_ui (x, 1, MPFR_RNDN);
330   mpfr_mul_2exp (x, x, 1024, MPFR_RNDN);
331   mpfr_set_double_range ();
332   mpfr_check_range (x, 0, MPFR_RNDD);
333   if (!mpfr_number_p (x))
334     {
335       printf ("Error: 2^1024 rounded down should give a normal number\n");
336       exit (1);
337     }
338 
339   mpfr_set_ui (x, 1, MPFR_RNDN);
340   mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
341   mpfr_add (x, x, x, MPFR_RNDN);
342   if (!mpfr_inf_p (x) || (mpfr_sgn(x) <= 0))
343     {
344       printf ("Error: x+x rounded to nearest for x=2^1023 should give +Inf\n");
345       printf ("emax = %ld\n", mpfr_get_emax ());
346       printf ("got "); mpfr_print_binary (x); puts ("");
347       exit (1);
348     }
349 
350   mpfr_set_ui (x, 1, MPFR_RNDN);
351   mpfr_mul_2exp (x, x, 1023, MPFR_RNDN);
352   mpfr_add (x, x, x, MPFR_RNDD);
353   if (!mpfr_number_p (x))
354     {
355       printf ("Error: x+x rounded down for x=2^1023 should give"
356               " a normal number\n");
357       exit (1);
358     }
359 
360   mpfr_set_ui (x, 1, MPFR_RNDN);
361   mpfr_div_2exp (x, x, 1022, MPFR_RNDN);
362   mpfr_set_str_binary (y, "1.1e-1022"); /* y = 3/2*x */
363   mpfr_sub (y, y, x, MPFR_RNDZ);
364   if (mpfr_cmp_ui (y, 0))
365     {
366       printf ("Error: y-x rounded to zero should give 0"
367               " for y=3/2*2^(-1022), x=2^(-1022)\n");
368       printf ("y="); mpfr_print_binary (y); puts ("");
369       exit (1);
370     }
371 
372   set_emin (-1026);
373   mpfr_set_ui (x, 1, MPFR_RNDN);
374   mpfr_div_2exp (x, x, 1025, MPFR_RNDN);
375   mpfr_set_double_range ();
376   mpfr_check_range (x, 0, MPFR_RNDN);
377   if (!MPFR_IS_ZERO (x) )
378     {
379       printf ("Error: x rounded to nearest for x=2^-1024 should give Zero\n");
380       printf ("emin = %ld\n", mpfr_get_emin ());
381       printf ("got "); mpfr_dump (x);
382       exit (1);
383     }
384 
385   mpfr_clear (x);
386   mpfr_clear (y);
387 
388   set_emin (emin);
389   set_emax (emax);
390 
391   check_emin_emax();
392   check_flags();
393   check_set_get_prec ();
394   check_powerof2 ();
395   check_set ();
396 
397   tests_end_mpfr ();
398   return 0;
399 }
400