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