xref: /netbsd-src/external/lgpl3/mpfr/dist/tests/tget_set_d64.c (revision 7d3af8c6a2070d16ec6d1aef203d052d6683100d)
1 /* Test file for mpfr_get_decimal64 and mpfr_set_decimal64.
2 
3 Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 Contributed by the Arenaire and Cacao 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 #include <stdlib.h> /* for exit */
24 #include "mpfr-test.h"
25 
26 /* #define DEBUG */
27 
28 #ifdef MPFR_WANT_DECIMAL_FLOATS
29 static void
30 print_decimal64 (_Decimal64 d)
31 {
32   union ieee_double_extract x;
33   union ieee_double_decimal64 y;
34   unsigned int Gh, i;
35 
36   y.d64 = d;
37   x.d = y.d;
38   Gh = x.s.exp >> 6;
39   printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1,
40           (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1);
41   printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1,
42           (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1,
43           x.s.exp & 1);
44   for (i = 20; i > 0; i--)
45     printf ("%d", (x.s.manh >> (i - 1)) & 1);
46   for (i = 32; i > 0; i--)
47     printf ("%d", (x.s.manl >> (i - 1)) & 1);
48   printf ("|\n");
49 }
50 
51 static void
52 check_inf_nan (void)
53 {
54   mpfr_t  x, y;
55   _Decimal64 d;
56 
57   mpfr_init2 (x, 123);
58   mpfr_init2 (y, 123);
59 
60   mpfr_set_nan (x);
61   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
62   mpfr_set_ui (x, 1, MPFR_RNDZ);
63   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
64   ASSERT_ALWAYS (mpfr_nan_p (x));
65 
66   mpfr_set_inf (x, 1);
67   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
68   mpfr_set_ui (x, 1, MPFR_RNDZ);
69   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
70   ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) > 0);
71 
72   mpfr_set_inf (x, -1);
73   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
74   mpfr_set_ui (x, 1, MPFR_RNDZ);
75   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
76   ASSERT_ALWAYS (mpfr_inf_p (x) && mpfr_sgn (x) < 0);
77 
78   mpfr_set_ui (x, 0, MPFR_RNDZ);
79   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
80   mpfr_set_ui (x, 1, MPFR_RNDZ);
81   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
82   ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) > 0);
83 
84   mpfr_set_ui (x, 0, MPFR_RNDZ);
85   mpfr_neg (x, x, MPFR_RNDZ);
86   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
87   mpfr_set_ui (x, 1, MPFR_RNDZ);
88   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
89   ASSERT_ALWAYS (mpfr_cmp_ui (x, 0) == 0 && MPFR_SIGN (x) < 0);
90 
91   mpfr_set_ui (x, 1, MPFR_RNDZ);
92   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
93   mpfr_set_ui (x, 0, MPFR_RNDZ);
94   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
95   ASSERT_ALWAYS (mpfr_cmp_ui (x, 1) == 0);
96 
97   mpfr_set_si (x, -1, MPFR_RNDZ);
98   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
99   mpfr_set_ui (x, 0, MPFR_RNDZ);
100   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
101   ASSERT_ALWAYS (mpfr_cmp_si (x, -1) == 0);
102 
103   mpfr_set_ui (x, 2, MPFR_RNDZ);
104   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
105   mpfr_set_ui (x, 0, MPFR_RNDZ);
106   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
107   ASSERT_ALWAYS (mpfr_cmp_ui (x, 2) == 0);
108 
109   mpfr_set_ui (x, 99, MPFR_RNDZ);
110   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
111   mpfr_set_ui (x, 0, MPFR_RNDZ);
112   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
113   ASSERT_ALWAYS (mpfr_cmp_ui (x, 99) == 0);
114 
115   mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ);
116   mpfr_set (y, x, MPFR_RNDZ);
117   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
118   mpfr_set_ui (x, 0, MPFR_RNDZ);
119   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
120   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
121 
122   /* smallest normal number */
123   mpfr_set_str (x, "1E-383", 10, MPFR_RNDU);
124   mpfr_set (y, x, MPFR_RNDZ);
125   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
126   mpfr_set_ui (x, 0, MPFR_RNDZ);
127   mpfr_set_decimal64 (x, d, MPFR_RNDU);
128   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
129 
130   /* smallest subnormal number */
131   mpfr_set_str (x, "1E-398", 10, MPFR_RNDU);
132   mpfr_set (y, x, MPFR_RNDZ);
133   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
134   mpfr_set_ui (x, 0, MPFR_RNDZ);
135   mpfr_set_decimal64 (x, d, MPFR_RNDU);
136   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
137 
138   /* subnormal number with exponent change when we round back
139      from 16 digits to 1 digit */
140   mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN);
141   d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */
142   mpfr_set_ui (x, 0, MPFR_RNDZ);
143   mpfr_set_decimal64 (x, d, MPFR_RNDD);
144   mpfr_set_str (y, "1E-397", 10, MPFR_RNDN);
145   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
146 
147   /* largest number */
148   mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
149   mpfr_set (y, x, MPFR_RNDZ);
150   d = mpfr_get_decimal64 (x, MPFR_RNDU);
151   mpfr_set_ui (x, 0, MPFR_RNDZ);
152   mpfr_set_decimal64 (x, d, MPFR_RNDZ);
153   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
154 
155   mpfr_set_prec (x, 53);
156   mpfr_set_prec (y, 53);
157 
158   /* largest number */
159   mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ);
160   d = mpfr_get_decimal64 (x, MPFR_RNDZ);
161   mpfr_set_decimal64 (y, d, MPFR_RNDU);
162   ASSERT_ALWAYS (mpfr_cmp (x, y) == 0);
163 
164   mpfr_clear (x);
165   mpfr_clear (y);
166 }
167 
168 static void
169 check_random (void)
170 {
171   mpfr_t  x, y;
172   _Decimal64 d;
173   int i;
174 
175   mpfr_init2 (x, 49);
176   mpfr_init2 (y, 49);
177 
178   for (i = 0; i < 100000; i++)
179     {
180       mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */
181       /* the normal decimal64 range contains [2^(-1272), 2^1278] */
182       mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN);
183       if (mpfr_get_exp (x) <= -1272)
184         mpfr_mul_2exp (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN);
185       d = mpfr_get_decimal64 (x, MPFR_RNDN);
186       mpfr_set_decimal64 (y, d, MPFR_RNDN);
187       if (mpfr_cmp (x, y) != 0)
188         {
189           printf ("x="); mpfr_dump (x);
190           printf ("d="); print_decimal64 (d);
191           printf ("y="); mpfr_dump (y);
192           exit (1);
193         }
194     }
195 
196   mpfr_clear (x);
197   mpfr_clear (y);
198 }
199 
200 /* check with native decimal formats */
201 static void
202 check_native (void)
203 {
204   mpfr_t x;
205   _Decimal64 d;
206 
207   mpfr_init2 (x, 53);
208 
209   /* check important constants are correctly converted */
210   mpfr_set_ui (x, 17, MPFR_RNDN);
211   d = mpfr_get_decimal64 (x, MPFR_RNDN);
212   MPFR_ASSERTN(d == 17.0dd);
213 
214   mpfr_set_ui (x, 42, MPFR_RNDN);
215   d = mpfr_get_decimal64 (x, MPFR_RNDN);
216   MPFR_ASSERTN(d == 42.0dd);
217 
218   mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN);
219   MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0);
220 
221   mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN);
222   MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0);
223 
224   mpfr_clear (x);
225 }
226 #endif /* MPFR_WANT_DECIMAL_FLOATS */
227 
228 int
229 main (void)
230 {
231   tests_start_mpfr ();
232   mpfr_test_init ();
233 
234 #ifdef MPFR_WANT_DECIMAL_FLOATS
235 #ifdef DEBUG
236 #ifdef DPD_FORMAT
237   printf ("Using DPD format\n");
238 #else
239   printf ("Using BID format\n");
240 #endif
241 #endif
242   check_inf_nan ();
243   check_random ();
244   check_native ();
245 #endif
246 
247   tests_end_mpfr ();
248   return 0;
249 }
250