xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tfits.c (revision c64d4171c6f912972428361000d29636c687d68b)
1 /* Test file for:
2  mpfr_fits_sint_p, mpfr_fits_slong_p, mpfr_fits_sshort_p,
3  mpfr_fits_uint_p, mpfr_fits_ulong_p, mpfr_fits_ushort_p
4 
5 Copyright 2004-2023 Free Software Foundation, Inc.
6 Contributed by the AriC and Caramba projects, INRIA.
7 
8 This file is part of the GNU MPFR Library.
9 
10 The GNU MPFR Library is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or (at your
13 option) any later version.
14 
15 The GNU MPFR Library is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
18 License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
22 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
23 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
24 
25 #define MPFR_NEED_INTMAX_H
26 #include "mpfr-test.h"
27 
28 #define FTEST_AUX(N,NOT,FCT)                                    \
29   do                                                            \
30     {                                                           \
31       __gmpfr_flags = ex_flags;                                 \
32       if (NOT FCT (x, (mpfr_rnd_t) r))                          \
33         {                                                       \
34           printf ("Error %d for %s, rnd = %s and x = ",         \
35                   N, #FCT,                                      \
36                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));        \
37           mpfr_dump (x);                                        \
38           exit (1);                                             \
39         }                                                       \
40       if (__gmpfr_flags != ex_flags)                            \
41         {                                                       \
42           mpfr_flags_t flags = __gmpfr_flags;                   \
43           printf ("Flags error %d for %s, rnd = %s and x = ",   \
44                   N, #FCT,                                      \
45                   mpfr_print_rnd_mode ((mpfr_rnd_t) r));        \
46           mpfr_dump(x);                                         \
47           printf ("Expected flags:");                           \
48           flags_out (ex_flags);                                 \
49           printf ("Got flags:     ");                           \
50           flags_out (flags);                                    \
51           exit (1);                                             \
52         }                                                       \
53     }                                                           \
54   while (0)
55 
56 #define FTEST(N,NOT,FCT)                                        \
57   do                                                            \
58     {                                                           \
59       mpfr_exp_t e;                                             \
60       FTEST_AUX (N,NOT,FCT);                                    \
61       if (MPFR_IS_SINGULAR (x))                                 \
62         break;                                                  \
63       e = mpfr_get_exp (x);                                     \
64       set_emin (e);                                             \
65       set_emax (e);                                             \
66       FTEST_AUX (N,NOT,FCT);                                    \
67       set_emin (emin);                                          \
68       set_emax (emax);                                          \
69     }                                                           \
70   while (0)
71 
72 #define CHECK_ALL(N,NOT)                                        \
73   do                                                            \
74     {                                                           \
75       FTEST (N, NOT, mpfr_fits_ulong_p);                        \
76       FTEST (N, NOT, mpfr_fits_slong_p);                        \
77       FTEST (N, NOT, mpfr_fits_uint_p);                         \
78       FTEST (N, NOT, mpfr_fits_sint_p);                         \
79       FTEST (N, NOT, mpfr_fits_ushort_p);                       \
80       FTEST (N, NOT, mpfr_fits_sshort_p);                       \
81     }                                                           \
82   while (0)
83 
84 #define CHECK_MAX(N,NOT)                                        \
85   do                                                            \
86     {                                                           \
87       FTEST (N, NOT, mpfr_fits_uintmax_p);                      \
88       FTEST (N, NOT, mpfr_fits_intmax_p);                       \
89     }                                                           \
90   while (0)
91 
92 /* V is a non-zero limit for the type (*_MIN for a signed type or *_MAX).
93  * If V is positive, then test V, V + 1/4, V + 3/4 and V + 1.
94  * If V is negative, then test V, V - 1/4, V - 3/4 and V - 1.
95  */
96 #define CHECK_LIM(N,V,SET,FCT)                                  \
97   do                                                            \
98     {                                                           \
99       SET (x, V, MPFR_RNDN);                                    \
100       FTEST (N, !, FCT);                                        \
101       mpfr_set_si_2exp (y, (V) < 0 ? -1 : 1, -2, MPFR_RNDN);    \
102       mpfr_add (x, x, y, MPFR_RNDN);                            \
103       FTEST (N+1, (r == MPFR_RNDN ||                            \
104                    MPFR_IS_LIKE_RNDZ (r, (V) < 0)) ^ !!, FCT);  \
105       mpfr_add (x, x, y, MPFR_RNDN);                            \
106       mpfr_add (x, x, y, MPFR_RNDN);                            \
107       FTEST (N+3, MPFR_IS_LIKE_RNDZ (r, (V) < 0) ^ !!, FCT);    \
108       mpfr_add (x, x, y, MPFR_RNDN);                            \
109       FTEST (N+4, !!, FCT);                                     \
110     }                                                           \
111   while (0)
112 
113 int
114 main (void)
115 {
116   mpfr_exp_t emin, emax;
117   mpfr_t x, y;
118   mpfr_flags_t flags[2] = { 0, MPFR_FLAGS_ALL }, ex_flags;
119   int i, r, fi;
120 
121   tests_start_mpfr ();
122 
123   emin = mpfr_get_emin ();
124   emax = mpfr_get_emax ();
125 
126   mpfr_init2 (x, sizeof (unsigned long) * CHAR_BIT + 2);
127   mpfr_init2 (y, 8);
128 
129   RND_LOOP (r)
130     for (fi = 0; fi < numberof (flags); fi++)
131       {
132         ex_flags = flags[fi];
133 
134         /* Check NaN */
135         mpfr_set_nan (x);
136         CHECK_ALL (1, !!);
137 
138         /* Check +Inf */
139         mpfr_set_inf (x, 1);
140         CHECK_ALL (2, !!);
141 
142         /* Check -Inf */
143         mpfr_set_inf (x, -1);
144         CHECK_ALL (3, !!);
145 
146         /* Check +0 */
147         mpfr_set_zero (x, 1);
148         CHECK_ALL (4, !);
149 
150         /* Check -0 */
151         mpfr_set_zero (x, -1);
152         CHECK_ALL (5, !);
153 
154         /* Check small positive op */
155         mpfr_set_str1 (x, "1@-1");
156         CHECK_ALL (6, !);
157 
158         /* Check 17 */
159         mpfr_set_ui (x, 17, MPFR_RNDN);
160         CHECK_ALL (7, !);
161 
162         /* Check large values (no fit) */
163         mpfr_set_ui (x, ULONG_MAX, MPFR_RNDN);
164         mpfr_mul_2ui (x, x, 1, MPFR_RNDN);
165         CHECK_ALL (8, !!);
166         mpfr_mul_2ui (x, x, 40, MPFR_RNDN);
167         CHECK_ALL (9, !!);
168 
169         /* Check a non-integer number just below a power of two. */
170         mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN);
171         CHECK_ALL (10, !);
172 
173         /* Check the limits of the types (except 0 for unsigned types) */
174         CHECK_LIM (20, ULONG_MAX, mpfr_set_ui, mpfr_fits_ulong_p);
175         CHECK_LIM (30, LONG_MAX, mpfr_set_si, mpfr_fits_slong_p);
176         CHECK_LIM (35, LONG_MIN, mpfr_set_si, mpfr_fits_slong_p);
177         CHECK_LIM (40, UINT_MAX, mpfr_set_ui, mpfr_fits_uint_p);
178         CHECK_LIM (50, INT_MAX, mpfr_set_si, mpfr_fits_sint_p);
179         CHECK_LIM (55, INT_MIN, mpfr_set_si, mpfr_fits_sint_p);
180         CHECK_LIM (60, USHRT_MAX, mpfr_set_ui, mpfr_fits_ushort_p);
181         CHECK_LIM (70, SHRT_MAX, mpfr_set_si, mpfr_fits_sshort_p);
182         CHECK_LIM (75, SHRT_MIN, mpfr_set_si, mpfr_fits_sshort_p);
183 
184         /* Check negative op */
185         for (i = 1; i <= 4; i++)
186           {
187             int inv;
188 
189             mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
190             /* for RNDF, it fits if it fits when rounding away from zero */
191             mpfr_rint (y, x, r != MPFR_RNDF ? (mpfr_rnd_t) r : MPFR_RNDA);
192             inv = MPFR_NOTZERO (y);
193             FTEST (80, inv ^ !, mpfr_fits_ulong_p);
194             FTEST (81,       !, mpfr_fits_slong_p);
195             FTEST (82, inv ^ !, mpfr_fits_uint_p);
196             FTEST (83,       !, mpfr_fits_sint_p);
197             FTEST (84, inv ^ !, mpfr_fits_ushort_p);
198             FTEST (85,       !, mpfr_fits_sshort_p);
199           }
200       }
201 
202 #ifdef _MPFR_H_HAVE_INTMAX_T
203 
204   mpfr_set_prec (x, sizeof (uintmax_t) * CHAR_BIT + 2);
205 
206   RND_LOOP (r)
207     {
208       /* Check NaN */
209       mpfr_set_nan (x);
210       CHECK_MAX (1, !!);
211 
212       /* Check +Inf */
213       mpfr_set_inf (x, 1);
214       CHECK_MAX (2, !!);
215 
216       /* Check -Inf */
217       mpfr_set_inf (x, -1);
218       CHECK_MAX (3, !!);
219 
220       /* Check +0 */
221       mpfr_set_zero (x, 1);
222       CHECK_MAX (4, !);
223 
224       /* Check -0 */
225       mpfr_set_zero (x, -1);
226       CHECK_MAX (5, !);
227 
228       /* Check small positive op */
229       mpfr_set_str1 (x, "1@-1");
230       CHECK_MAX (6, !);
231 
232       /* Check 17 */
233       mpfr_set_ui (x, 17, MPFR_RNDN);
234       CHECK_MAX (7, !);
235 
236       /* Check hugest */
237       mpfr_set_ui_2exp (x, 42, sizeof (uintmax_t) * 32, MPFR_RNDN);
238       CHECK_MAX (8, !!);
239 
240       /* Check a non-integer number just below a power of two. */
241       mpfr_set_ui_2exp (x, 255, -2, MPFR_RNDN);
242       CHECK_MAX (10, !);
243 
244       /* Check the limits of the types (except 0 for uintmax_t) */
245       CHECK_LIM (20, UINTMAX_MAX, mpfr_set_uj, mpfr_fits_uintmax_p);
246       CHECK_LIM (30, INTMAX_MAX, mpfr_set_sj, mpfr_fits_intmax_p);
247       CHECK_LIM (35, INTMAX_MIN, mpfr_set_sj, mpfr_fits_intmax_p);
248 
249       /* Check negative op */
250       for (i = 1; i <= 4; i++)
251         {
252           int inv;
253 
254           mpfr_set_si_2exp (x, -i, -2, MPFR_RNDN);
255           mpfr_rint (y, x, (mpfr_rnd_t) r);
256           inv = MPFR_NOTZERO (y);
257           if (r != MPFR_RNDF)
258             FTEST (80, inv ^ !, mpfr_fits_uintmax_p);
259           else
260             FTEST (80, !!, mpfr_fits_uintmax_p);
261           FTEST (81,       !, mpfr_fits_intmax_p);
262         }
263     }
264 
265 #endif  /* _MPFR_H_HAVE_INTMAX_T */
266 
267   mpfr_clear (x);
268   mpfr_clear (y);
269 
270   tests_end_mpfr ();
271   return 0;
272 }
273