xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tget_sj.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /* Test file for mpfr_get_sj and mpfr_get_uj.
2 
3 Copyright 2004-2016 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 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 #ifdef HAVE_CONFIG_H
24 # include "config.h"       /* for a build within gmp */
25 #endif
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 
30 #include "mpfr-intmax.h"
31 #include "mpfr-test.h"
32 
33 #ifndef _MPFR_H_HAVE_INTMAX_T
34 
35 int
36 main (void)
37 {
38   return 77;
39 }
40 
41 #else
42 
43 static void
44 check_sj (intmax_t s, mpfr_ptr x)
45 {
46   mpfr_t y;
47   int i;
48 
49   mpfr_init2 (y, MPFR_PREC (x));
50 
51   for (i = -1; i <= 1; i++)
52     {
53       int rnd;
54 
55       mpfr_set_si_2exp (y, i, -2, MPFR_RNDN);
56       mpfr_add (y, y, x, MPFR_RNDN);
57       for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
58         {
59           intmax_t r;
60 
61           if (rnd == MPFR_RNDZ && i < 0 && s >= 0)
62             continue;
63           if (rnd == MPFR_RNDZ && i > 0 && s <= 0)
64             continue;
65           if (rnd == MPFR_RNDD && i < 0)
66             continue;
67           if (rnd == MPFR_RNDU && i > 0)
68             continue;
69           if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) ||
70                                   (MPFR_IS_NEG(y) && i < 0)))
71             continue;
72           /* rint (y) == x == s */
73           r = mpfr_get_sj (y, (mpfr_rnd_t) rnd);
74           if (r != s)
75             {
76               printf ("Error in check_sj for y = ");
77               mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
78               printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
79               printf ("Got %jd instead of %jd.\n", r, s);
80               exit (1);
81             }
82         }
83     }
84 
85   mpfr_clear (y);
86 }
87 
88 static void
89 check_uj (uintmax_t u, mpfr_ptr x)
90 {
91   mpfr_t y;
92   int i;
93 
94   mpfr_init2 (y, MPFR_PREC (x));
95 
96   for (i = -1; i <= 1; i++)
97     {
98       int rnd;
99 
100       mpfr_set_si_2exp (y, i, -2, MPFR_RNDN);
101       mpfr_add (y, y, x, MPFR_RNDN);
102       for (rnd = 0; rnd < MPFR_RND_MAX; rnd++)
103         {
104           uintmax_t r;
105 
106           if (rnd == MPFR_RNDZ && i < 0)
107             continue;
108           if (rnd == MPFR_RNDD && i < 0)
109             continue;
110           if (rnd == MPFR_RNDU && i > 0)
111             continue;
112           if (rnd == MPFR_RNDA && ((MPFR_IS_POS(y) && i > 0) ||
113                                   (MPFR_IS_NEG(y) && i < 0)))
114             continue;
115           /* rint (y) == x == u */
116           r = mpfr_get_uj (y, (mpfr_rnd_t) rnd);
117           if (r != u)
118             {
119               printf ("Error in check_uj for y = ");
120               mpfr_out_str (stdout, 2, 0, y, MPFR_RNDN);
121               printf (" in %s\n", mpfr_print_rnd_mode ((mpfr_rnd_t) rnd));
122               printf ("Got %ju instead of %ju.\n", r, u);
123               exit (1);
124             }
125         }
126     }
127 
128   mpfr_clear (y);
129 }
130 
131 static void
132 check_erange (void)
133 {
134   mpfr_t x;
135   uintmax_t dl;
136   intmax_t d;
137 
138   /* Test for ERANGE flag + correct behaviour if overflow */
139 
140   mpfr_init2 (x, 256);
141   mpfr_set_uj (x, MPFR_UINTMAX_MAX, MPFR_RNDN);
142   mpfr_clear_erangeflag ();
143   dl = mpfr_get_uj (x, MPFR_RNDN);
144   if (dl != MPFR_UINTMAX_MAX || mpfr_erangeflag_p ())
145     {
146       printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (1)\n");
147       exit (1);
148     }
149   mpfr_add_ui (x, x, 1, MPFR_RNDN);
150   dl = mpfr_get_uj (x, MPFR_RNDN);
151   if (dl != MPFR_UINTMAX_MAX || !mpfr_erangeflag_p ())
152     {
153       printf ("ERROR for get_uj + ERANGE + UINTMAX_MAX (2)\n");
154       exit (1);
155     }
156   mpfr_set_sj (x, -1, MPFR_RNDN);
157   mpfr_clear_erangeflag ();
158   dl = mpfr_get_uj (x, MPFR_RNDN);
159   if (dl != 0 || !mpfr_erangeflag_p ())
160     {
161       printf ("ERROR for get_uj + ERANGE + -1 \n");
162       exit (1);
163     }
164   mpfr_set_sj (x, MPFR_INTMAX_MAX, MPFR_RNDN);
165   mpfr_clear_erangeflag ();
166   d = mpfr_get_sj (x, MPFR_RNDN);
167   if (d != MPFR_INTMAX_MAX || mpfr_erangeflag_p ())
168     {
169       printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (1)\n");
170       exit (1);
171     }
172   mpfr_add_ui (x, x, 1, MPFR_RNDN);
173   d = mpfr_get_sj (x, MPFR_RNDN);
174   if (d != MPFR_INTMAX_MAX || !mpfr_erangeflag_p ())
175     {
176       printf ("ERROR for get_sj + ERANGE + INTMAX_MAX (2)\n");
177       exit (1);
178     }
179   mpfr_set_sj (x, MPFR_INTMAX_MIN, MPFR_RNDN);
180   mpfr_clear_erangeflag ();
181   d = mpfr_get_sj (x, MPFR_RNDN);
182   if (d != MPFR_INTMAX_MIN || mpfr_erangeflag_p ())
183     {
184       printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (1)\n");
185       exit (1);
186     }
187   mpfr_sub_ui (x, x, 1, MPFR_RNDN);
188   d = mpfr_get_sj (x, MPFR_RNDN);
189   if (d != MPFR_INTMAX_MIN || !mpfr_erangeflag_p ())
190     {
191       printf ("ERROR for get_sj + ERANGE + INTMAX_MIN (2)\n");
192       exit (1);
193     }
194 
195   mpfr_set_nan (x);
196   mpfr_clear_erangeflag ();
197   d = mpfr_get_uj (x, MPFR_RNDN);
198   if (d != 0 || !mpfr_erangeflag_p ())
199     {
200       printf ("ERROR for get_uj + NaN\n");
201       exit (1);
202     }
203   mpfr_clear_erangeflag ();
204   d = mpfr_get_sj (x, MPFR_RNDN);
205   if (d != 0 || !mpfr_erangeflag_p ())
206     {
207       printf ("ERROR for get_sj + NaN\n");
208       exit (1);
209     }
210 
211   mpfr_clear (x);
212 }
213 
214 int
215 main (void)
216 {
217   mpfr_prec_t prec;
218   mpfr_t x, y;
219   intmax_t s;
220   uintmax_t u;
221 
222   tests_start_mpfr ();
223 
224   for (u = MPFR_UINTMAX_MAX, prec = 0; u != 0; u /= 2, prec++)
225     { }
226 
227   mpfr_init2 (x, prec + 4);
228   mpfr_init2 (y, prec + 4);
229 
230   mpfr_set_ui (x, 0, MPFR_RNDN);
231   check_sj (0, x);
232   check_uj (0, x);
233 
234   mpfr_set_ui (x, 1, MPFR_RNDN);
235   check_sj (1, x);
236   check_uj (1, x);
237 
238   mpfr_neg (x, x, MPFR_RNDN);
239   check_sj (-1, x);
240 
241   mpfr_set_si_2exp (x, 1, prec, MPFR_RNDN);
242   mpfr_sub_ui (x, x, 1, MPFR_RNDN); /* UINTMAX_MAX */
243 
244   mpfr_div_ui (y, x, 2, MPFR_RNDZ);
245   mpfr_trunc (y, y); /* INTMAX_MAX */
246   for (s = MPFR_INTMAX_MAX; s != 0; s /= 17)
247     {
248       check_sj (s, y);
249       mpfr_div_ui (y, y, 17, MPFR_RNDZ);
250       mpfr_trunc (y, y);
251     }
252 
253   mpfr_div_ui (y, x, 2, MPFR_RNDZ);
254   mpfr_trunc (y, y); /* INTMAX_MAX */
255   mpfr_neg (y, y, MPFR_RNDN);
256   if (MPFR_INTMAX_MIN + MPFR_INTMAX_MAX != 0)
257     mpfr_sub_ui (y, y, 1, MPFR_RNDN); /* INTMAX_MIN */
258   for (s = MPFR_INTMAX_MIN; s != 0; s /= 17)
259     {
260       check_sj (s, y);
261       mpfr_div_ui (y, y, 17, MPFR_RNDZ);
262       mpfr_trunc (y, y);
263     }
264 
265   for (u = MPFR_UINTMAX_MAX; u != 0; u /= 17)
266     {
267       check_uj (u, x);
268       mpfr_div_ui (x, x, 17, MPFR_RNDZ);
269       mpfr_trunc (x, x);
270     }
271 
272   mpfr_clear (x);
273   mpfr_clear (y);
274 
275   check_erange ();
276 
277   tests_end_mpfr ();
278   return 0;
279 }
280 
281 #endif
282