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