xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tget_set_d64.c (revision e89934bbf778a6d6d6894877c4da59d0c7835b0f)
1 /* Test file for mpfr_get_decimal64 and mpfr_set_decimal64.
2 
3 Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
4 Contributed by the AriC and Caramel 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 MPFR_WANT_DECIMAL_FLOATS
24 
25 #include <stdlib.h> /* for exit */
26 #include "mpfr-test.h"
27 
28 #ifndef DEC64_MAX
29 # define DEC64_MAX 9.999999999999999E384dd
30 #endif
31 
32 /* #define DEBUG */
33 
34 static void
35 print_decimal64 (_Decimal64 d)
36 {
37   union ieee_double_extract x;
38   union ieee_double_decimal64 y;
39   unsigned int Gh, i;
40 
41   y.d64 = d;
42   x.d = y.d;
43   Gh = x.s.exp >> 6;
44   printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1,
45           (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1);
46   printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1,
47           (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1,
48           x.s.exp & 1);
49   for (i = 20; i > 0; i--)
50     printf ("%d", (x.s.manh >> (i - 1)) & 1);
51   for (i = 32; i > 0; i--)
52     printf ("%d", (x.s.manl >> (i - 1)) & 1);
53   printf ("|\n");
54 }
55 
56 static void
57 check_inf_nan (void)
58 {
59   mpfr_t  x, y;
60   _Decimal64 d;
61 
62   mpfr_init2 (x, 123);
63   mpfr_init2 (y, 123);
64 
65   mpfr_set_nan (x);
66   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
67   mpfr_set_ui (x, 1, MPFR_RNDZ);
68   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
69   ASSERT_ALWAYS (mpfr_nan_p (x));
70 
71   mpfr_set_inf (x, 1);
72   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
73   mpfr_set_ui (x, 1, MPFR_RNDZ);
74   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
75   ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) > 0);
76 
77   mpfr_set_inf (x, -1);
78   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
79   mpfr_set_ui (x, 1, MPFR_RNDZ);
80   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
81   ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) < 0);
82 
83   mpfr_set_ui (x, 0, MPFR_RNDZ);
84   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
85   mpfr_set_ui (x, 1, MPFR_RNDZ);
86   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
87   ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) > 0);
88 
89   mpfr_set_ui (x, 0, MPFR_RNDZ);
90   mpfr_neg (x, x, MPFR_RNDZ);
91   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
92   mpfr_set_ui (x, 1, MPFR_RNDZ);
93   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
94   ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) < 0);
95 
96   mpfr_set_ui (x, 1, MPFR_RNDZ);
97   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
98   mpfr_set_ui (x, 0, MPFR_RNDZ);
99   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
100   ASSERT_ALWAYS (mpfr_cmp_ui (x, 1) == 0);
101 
102   mpfr_set_si (x, -1, MPFR_RNDZ);
103   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
104   mpfr_set_ui (x, 0, MPFR_RNDZ);
105   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
106   ASSERT_ALWAYS (mpfr_cmp_si (x, -1) == 0);
107 
108   mpfr_set_ui (x, 2, MPFR_RNDZ);
109   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
110   mpfr_set_ui (x, 0, MPFR_RNDZ);
111   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
112   ASSERT_ALWAYS (mpfr_cmp_ui (x, 2) == 0);
113 
114   mpfr_set_ui (x, 99, MPFR_RNDZ);
115   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
116   mpfr_set_ui (x, 0, MPFR_RNDZ);
117   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
118   ASSERT_ALWAYS (mpfr_cmp_ui (x, 99) == 0);
119 
120   mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ);
121   mpfr_set (y, x, MPFR_RNDZ);
122   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
123   mpfr_set_ui (x, 0, MPFR_RNDZ);
124   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
125   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
126 
127   /* smallest normal number */
128   mpfr_set_str (x, "1E-383", 10, MPFR_RNDU);
129   mpfr_set (y, x, MPFR_RNDZ);
130   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
131   mpfr_set_ui (x, 0, MPFR_RNDZ);
132   mpfr_set_decimal64 (x, d, MPFR_RNDU);
133   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
134 
135   /* smallest subnormal number */
136   mpfr_set_str (x, "1E-398", 10, MPFR_RNDU);
137   mpfr_set (y, x, MPFR_RNDZ);
138   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
139   mpfr_set_ui (x, 0, MPFR_RNDZ);
140   mpfr_set_decimal64 (x, d, MPFR_RNDU);
141   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
142 
143   /* subnormal number with exponent change when we round back
144      from 16 digits to 1 digit */
145   mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN);
146   d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */
147   mpfr_set_ui (x, 0, MPFR_RNDZ);
148   mpfr_set_decimal64 (x, d, MPFR_RNDD);
149   mpfr_set_str (y, "1E-397", 10, MPFR_RNDN);
150   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
151 
152   /* largest number */
153   mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
154   mpfr_set (y, x, MPFR_RNDZ);
155   d = mpfr_get_decimal64 (x, MPFR_RNDU);
156   ASSERT_ALWAYS (d == DEC64_MAX);
157   mpfr_set_ui (x, 0, MPFR_RNDZ);
158   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
159   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
160 
161   mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ);
162   mpfr_set (y, x, MPFR_RNDZ);
163   d = mpfr_get_decimal64 (x, MPFR_RNDA);
164   ASSERT_ALWAYS (d == -DEC64_MAX);
165   mpfr_set_ui (x, 0, MPFR_RNDZ);
166   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
167   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
168 
169   mpfr_set_prec (x, 53);
170   mpfr_set_prec (y, 53);
171 
172   /* largest number */
173   mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
174   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
175   mpfr_set_decimal64 (y, d, MPFR_RNDU);
176   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
177 
178   mpfr_clear (x);
179   mpfr_clear (y);
180 }
181 
182 static void
183 check_random (void)
184 {
185   mpfr_t  x, y;
186   _Decimal64 d;
187   int i;
188 
189   mpfr_init2 (x, 49);
190   mpfr_init2 (y, 49);
191 
192   for (i = 0; i < 100000; i++)
193     {
194       mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */
195       /* the normal decimal64 range contains [2^(-1272), 2^1278] */
196       mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN);
197       if (mpfr_get_exp (x) <= -1272)
198         mpfr_mul_2exp (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN);
199       d = mpfr_get_decimal64 (x, MPFR_RNDN);
200       mpfr_set_decimal64 (y, d, MPFR_RNDN);
201       if (mpfr_cmp (x, y) != 0)
202         {
203           printf ("x="); mpfr_dump (x);
204           printf ("d="); print_decimal64 (d);
205           printf ("y="); mpfr_dump (y);
206           exit (1);
207         }
208     }
209 
210   mpfr_clear (x);
211   mpfr_clear (y);
212 }
213 
214 /* check with native decimal formats */
215 static void
216 check_native (void)
217 {
218   mpfr_t x;
219   _Decimal64 d;
220 
221   mpfr_init2 (x, 53);
222 
223   /* check important constants are correctly converted */
224   mpfr_set_ui (x, 17, MPFR_RNDN);
225   d = mpfr_get_decimal64 (x, MPFR_RNDN);
226   MPFR_ASSERTN(d == 17.0dd);
227 
228   mpfr_set_ui (x, 42, MPFR_RNDN);
229   d = mpfr_get_decimal64 (x, MPFR_RNDN);
230   MPFR_ASSERTN(d == 42.0dd);
231 
232   mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN);
233   MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0);
234 
235   mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN);
236   MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0);
237 
238   mpfr_clear (x);
239 }
240 
241 static void
242 check_overflow (void)
243 {
244   mpfr_t x;
245   int err = 0, neg, rnd;
246 
247   mpfr_init2 (x, 96);
248   for (neg = 0; neg < 2; neg++)
249     RND_LOOP (rnd)
250       {
251         _Decimal64 d, e;
252         mpfr_rnd_t r = (mpfr_rnd_t) rnd;
253         int sign = neg ? -1 : 1;
254 
255         e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX;
256         /* This tests the binary exponent e > 1279 case of get_d64.c */
257         mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN);
258         d = mpfr_get_decimal64 (x, r);
259         if (d != e)
260           {
261             printf ("Error 1 in check_overflow for %s, %s\n",
262                     neg ? "negative" : "positive",
263                     mpfr_print_rnd_mode (r));
264             err = 1;
265           }
266         /* This tests the decimal exponent e > 385 case of get_d64.c */
267         mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN);
268         d = mpfr_get_decimal64 (x, r);
269         if (d != e)
270           {
271             printf ("Error 2 in check_overflow for %s, %s\n",
272                     neg ? "negative" : "positive",
273                     mpfr_print_rnd_mode (r));
274             err = 1;
275           }
276         /* This tests the last else (-382 <= e <= 385) of get_d64.c */
277         mpfr_set_decimal64 (x, e, MPFR_RNDA);
278         d = mpfr_get_decimal64 (x, r);
279         if (d != e)
280           {
281             printf ("Error 3 in check_overflow for %s, %s\n",
282                     neg ? "negative" : "positive",
283                     mpfr_print_rnd_mode (r));
284             err = 1;
285           }
286       }
287   mpfr_clear (x);
288   if (err)
289     exit (1);
290 }
291 
292 static void
293 check_tiny (void)
294 {
295   mpfr_t x;
296   _Decimal64 d;
297 
298   /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round
299      to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between
300      0 and 1E-398 is not a representable binary number, so that there
301      are no tests for it. */
302   mpfr_init2 (x, 128);
303   mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ);
304   d = mpfr_get_decimal64 (x, MPFR_RNDN);
305   MPFR_ASSERTN (d == 1.0E-398dd);
306   mpfr_neg (x, x, MPFR_RNDN);
307   d = mpfr_get_decimal64 (x, MPFR_RNDN);
308   MPFR_ASSERTN (d == -1.0E-398dd);
309   mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU);
310   d = mpfr_get_decimal64 (x, MPFR_RNDN);
311   MPFR_ASSERTN (d == 1.0E-398dd);
312   mpfr_neg (x, x, MPFR_RNDN);
313   d = mpfr_get_decimal64 (x, MPFR_RNDN);
314   MPFR_ASSERTN (d == -1.0E-398dd);
315   mpfr_clear (x);
316 }
317 
318 int
319 main (void)
320 {
321   tests_start_mpfr ();
322   mpfr_test_init ();
323 
324 #ifdef DEBUG
325 #ifdef DPD_FORMAT
326   printf ("Using DPD format\n");
327 #else
328   printf ("Using BID format\n");
329 #endif
330 #endif
331   check_inf_nan ();
332   check_random ();
333   check_native ();
334   check_overflow ();
335   check_tiny ();
336 
337   tests_end_mpfr ();
338   return 0;
339 }
340 
341 #else /* MPFR_WANT_DECIMAL_FLOATS */
342 
343 int
344 main (void)
345 {
346   return 77;
347 }
348 
349 #endif /* MPFR_WANT_DECIMAL_FLOATS */
350