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