xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tmodf.c (revision c5e820cae412164fcbee52f470436200af5358ea)
1 /* Test file for mpfr_modf.
2 
3 Copyright 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 #if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)
29 
30 static void
31 check (const char *xis, const char *xfs, const char *xs,
32        mpfr_prec_t xip, mpfr_prec_t xfp, mpfr_prec_t xp,
33        int expected_return, mpfr_rnd_t rnd_mode)
34 {
35   int inexact;
36   mpfr_t xi, xf, x;
37 
38   mpfr_init2 (xi, xip);
39   mpfr_init2 (xf, xfp);
40   mpfr_init2 (x, xp);
41   mpfr_set_str1 (x, xs);
42   inexact = mpfr_modf (xi, xf, x, rnd_mode);
43   if (mpfr_cmp_str1 (xi, xis))
44     {
45       printf ("mpfr_modf failed for x=%s, rnd=%s\n",
46               xs, mpfr_print_rnd_mode(rnd_mode));
47       printf ("got integer value: ");
48       mpfr_out_str (stdout, 10, 0, xi, MPFR_RNDN);
49       printf ("\nexpected %s\n", xis);
50       exit (1);
51     }
52   if (mpfr_cmp_str1 (xf, xfs))
53     {
54       printf ("mpfr_modf failed for x=%s, rnd=%s\n",
55               xs, mpfr_print_rnd_mode(rnd_mode));
56       printf ("got fractional value: ");
57       mpfr_out_str (stdout, 10, 0, xf, MPFR_RNDN);
58       printf ("\nexpected %s\n", xfs);
59       exit (1);
60     }
61   if (inexact != expected_return)
62     {
63       printf ("mpfr_modf failed for x=%s, rnd=%s\n",
64               xs, mpfr_print_rnd_mode(rnd_mode));
65       printf ("got return value: %d, expected %d\n", inexact, expected_return);
66       exit (1);
67     }
68   mpfr_clears (xi, xf, x, (mpfr_ptr) 0);
69 }
70 
71 static void
72 check_nans (void)
73 {
74   mpfr_t  x, xi, xf;
75 
76   mpfr_init2 (x, 123);
77   mpfr_init2 (xi, 123);
78   mpfr_init2 (xf, 123);
79 
80   /* nan */
81   mpfr_set_nan (x);
82   mpfr_modf (xi, xf, x, MPFR_RNDN);
83   MPFR_ASSERTN (mpfr_nan_p (xi));
84   MPFR_ASSERTN (mpfr_nan_p (xf));
85 
86   /* +inf */
87   mpfr_set_inf (x, 1);
88   mpfr_modf (xi, xf, x, MPFR_RNDN);
89   MPFR_ASSERTN (mpfr_inf_p (xi));
90   MPFR_ASSERTN (mpfr_sgn (xi) > 0);
91   MPFR_ASSERTN (mpfr_zero_p (xf));
92 
93   /* -inf */
94   mpfr_set_inf (x, -1);
95   mpfr_modf (xi ,xf, x, MPFR_RNDN);
96   MPFR_ASSERTN (mpfr_inf_p (xi));
97   MPFR_ASSERTN (mpfr_sgn (xi) < 0);
98   MPFR_ASSERTN (mpfr_zero_p (xf));
99 
100   mpfr_clear (x);
101   mpfr_clear (xi);
102   mpfr_clear (xf);
103 }
104 
105 static void
106 check_special_exprange (void)
107 {
108   int inexact, ov;
109   unsigned int eflags, gflags;
110   mpfr_t xi, xf, x;
111   mpfr_exp_t emax;
112 
113   emax = mpfr_get_emax ();
114   mpfr_init2 (xi, 7);
115   mpfr_init2 (xf, 7);
116   mpfr_init2 (x, 8);
117 
118   mpfr_set_str (x, "0.11111111", 2, MPFR_RNDN);
119   for (ov = 0; ov <= 1; ov++)
120     {
121       const char *s = ov ? "@Inf@" : "1";
122 
123       if (ov)
124         set_emax (0);
125       mpfr_clear_flags ();
126       inexact = mpfr_modf (xi, xf, x, MPFR_RNDN);
127       gflags = __gmpfr_flags;
128       set_emax (emax);
129       if (MPFR_NOTZERO (xi) || MPFR_IS_NEG (xi) ||
130           mpfr_cmp_str1 (xf, s) != 0)
131         {
132           printf ("Error in check_special_exprange (ov = %d):"
133                   " expected 0 and %s, got\n", ov, s);
134           mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN);
135           printf (" and ");
136           mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN);
137           printf ("\n");
138           exit (1);
139         }
140       if (inexact != 4)
141         {
142           printf ("Bad inexact value in check_special_exprange (ov = %d):"
143                   " expected 4, got %d\n", ov, inexact);
144           exit (1);
145         }
146       eflags = MPFR_FLAGS_INEXACT | (ov ? MPFR_FLAGS_OVERFLOW : 0);
147       if (gflags != eflags)
148         {
149           printf ("Bad flags in check_special_exprange (ov = %d):"
150                   " expected %u, got %u\n", ov, eflags, gflags);
151           exit (1);
152         }
153     }
154 
155   /* Test if an overflow occurs in mpfr_set for ope >= opq. */
156   mpfr_set_emax (MPFR_EMAX_MAX);
157   mpfr_set_inf (x, 1);
158   mpfr_nextbelow (x);
159   mpfr_clear_flags ();
160   inexact = mpfr_modf (xi, xf, x, MPFR_RNDN);
161   gflags = __gmpfr_flags;
162   if (mpfr_cmp_str1 (xi, "@Inf@") != 0 ||
163       MPFR_NOTZERO (xf) || MPFR_IS_NEG (xf))
164     {
165       printf ("Error in check_special_exprange:"
166               " expected 0 and @Inf@, got\n");
167       mpfr_out_str (stdout, 2, 0, xi, MPFR_RNDN);
168       printf (" and ");
169       mpfr_out_str (stdout, 2, 0, xf, MPFR_RNDN);
170       printf ("\n");
171       exit (1);
172     }
173   if (inexact != 1)
174     {
175       printf ("Bad inexact value in check_special_exprange:"
176               " expected 1, got %d\n", inexact);
177       exit (1);
178     }
179   eflags = MPFR_FLAGS_INEXACT | MPFR_FLAGS_OVERFLOW;
180   if (gflags != eflags)
181     {
182       printf ("Bad flags in check_special_exprange:"
183               " expected %u, got %u\n", eflags, gflags);
184       exit (1);
185     }
186   set_emax (emax);
187 
188   /* Test if an underflow occurs in the general case. TODO */
189 
190   mpfr_clears (xi, xf, x, (mpfr_ptr) 0);
191 }
192 
193 int
194 main (int argc, char *argv[])
195 {
196   tests_start_mpfr ();
197 
198   check_nans ();
199 
200   /* integer part is exact, frac. part is exact: return value should be 0 */
201   check ("61680","3.52935791015625e-1", "61680.352935791015625",
202          53, 53, 53, 0, MPFR_RNDZ);
203   /* integer part is rounded up, fractional part is rounded up: return value
204      should be 1+4*1=5 */
205   check ("-53968","-3.529052734375e-1", "-53970.352935791015625",
206          13, 13, 53, 5, MPFR_RNDZ);
207   /* integer part is rounded down, fractional part is rounded down:
208      return value should be 2+4*2=10 */
209   check ("61632","3.525390625e-1",      "61648.352935791015625",
210          10, 10, 53, 10, MPFR_RNDZ);
211   check ("61680", "0", "61680",  53, 53, 53, 0, MPFR_RNDZ);
212   /* integer part is rounded up, fractional part is exact: 1 */
213   check ("-53968","0", "-53970", 13, 13, 53, 1, MPFR_RNDZ);
214   /* integer part is rounded up, fractional part is exact: 1 */
215   check ("-43392","0", "-43399", 13, 13, 53, 1, MPFR_RNDU);
216   /* integer part is rounded down, fractional part is exact: 2 */
217   check ("-52720","0", "-52719", 13, 13, 53, 2, MPFR_RNDD);
218   /* integer part is rounded down, fractional part is exact: 2 */
219   check ("61632", "0", "61648",  10, 10, 53, 2, MPFR_RNDZ);
220 
221   check_special_exprange ();
222 
223   tests_end_mpfr ();
224   return 0;
225 }
226 
227 #else
228 
229 int
230 main (void)
231 {
232   printf ("Warning! Test disabled for this MPFR version.\n");
233   return 0;
234 }
235 
236 #endif
237