xref: /netbsd/external/lgpl3/gmp/dist/tests/mpf/t-conv.c (revision 122966f8)
1 /* Test mpf_get_str and mpf_set_str.
2 
3 Copyright 1996, 2000, 2001, 2008, 2019, 2020 Free Software Foundation, Inc.
4 
5 This file is part of the GNU MP Library test suite.
6 
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11 
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15 Public License for more details.
16 
17 You should have received a copy of the GNU General Public License along with
18 the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h> /* for strlen */
23 
24 #include "gmp-impl.h"
25 #include "tests.h"
26 
27 #ifndef SIZE
28 #define SIZE 10
29 #endif
30 
31 #ifndef EXPO
32 #define EXPO 200
33 #endif
34 
35 int
main(int argc,char ** argv)36 main (int argc, char **argv)
37 {
38   mpf_t x, y;
39   int reps = 20000;
40   int i;
41   mp_size_t bprec = 100;
42   mpf_t d, rerr, max_rerr, limit_rerr;
43   char *str;
44   mp_exp_t bexp;
45   long size, exp;
46   int base;
47   char buf[SIZE * GMP_LIMB_BITS + 5];
48 
49   tests_start ();
50 
51   if (argc > 1)
52     {
53       reps = strtol (argv[1], 0, 0);
54       if (argc > 2)
55 	bprec = strtol (argv[2], 0, 0);
56     }
57 
58   mpf_set_default_prec (bprec);
59 
60   mpf_init_set_ui (limit_rerr, 1);
61   mpf_div_2exp (limit_rerr, limit_rerr, bprec);
62 #if VERBOSE
63   mpf_dump (limit_rerr);
64 #endif
65   mpf_init (rerr);
66   mpf_init_set_ui (max_rerr, 0);
67 
68   mpf_init (x);
69   mpf_init (y);
70   mpf_init (d);
71 
72   /* First test some specific values.  */
73 
74   mpf_set_str (y, "1.23456", 0);
75   mpf_set_str (x, "1.23456", 10);
76   MPF_CHECK_FORMAT (x);
77   if (mpf_cmp (x, y) != 0)
78     abort ();
79   mpf_set_str (x, "00000000000000000000000000000000000000001.23456", 10);
80   MPF_CHECK_FORMAT (x);
81   if (mpf_cmp (x, y) != 0)
82     abort ();
83   mpf_set_str (x, "0.000000000000000000000000000000000000000123456e40", 10);
84   MPF_CHECK_FORMAT (x);
85   if (mpf_cmp (x, y) != 0)
86     abort ();
87   mpf_set_str (x, ".000000000000000000000000000000000000000123456e40", 10);
88   MPF_CHECK_FORMAT (x);
89   if (mpf_cmp (x, y) != 0)
90     abort ();
91   mpf_set_str (x, "00000000000000000000.00000000000000000000123456e21", 10);
92   MPF_CHECK_FORMAT (x);
93   if (mpf_cmp (x, y) != 0)
94     abort ();
95 
96   mpf_set_str (y, "1.23456e1000", 0);
97   mpf_set_str (x, "1.23456e1000", 10);
98   if (mpf_cmp (x, y) != 0)
99     abort ();
100   mpf_set_str (x, "1.23456e+1000", 0);
101   if (mpf_cmp (x, y) != 0)
102     abort ();
103   mpf_set_str (x, "1.23456e+1000", 10);
104   if (mpf_cmp (x, y) != 0)
105     abort ();
106   mpf_set_str (x, "00000000000000000000000000000000000000001.23456e+1000", 10);
107   MPF_CHECK_FORMAT (x);
108   if (mpf_cmp (x, y) != 0)
109     abort ();
110   mpf_set_str (x, "0.000000000000000000000000000000000000000123456e+1040", 10);
111   MPF_CHECK_FORMAT (x);
112   if (mpf_cmp (x, y) != 0)
113     abort ();
114   mpf_set_str (x, ".000000000000000000000000000000000000000123456e+1040", 10);
115   MPF_CHECK_FORMAT (x);
116   if (mpf_cmp (x, y) != 0)
117     abort ();
118   mpf_set_str (x, "00000000000000000000.00000000000000000000123456e+1021", 10);
119   MPF_CHECK_FORMAT (x);
120   if (mpf_cmp (x, y) != 0)
121     abort ();
122 
123   mpf_set_str (y, "1.23456", 16);
124   mpf_set_str (x, "00000000000000000000000000000000000000001.23456", 16);
125   MPF_CHECK_FORMAT (x);
126   if (mpf_cmp (x, y) != 0)
127     abort ();
128   mpf_set_str (x, "0.000000000000000000000000000000000000000123456@28", 16);
129   MPF_CHECK_FORMAT (x);
130   if (mpf_cmp (x, y) != 0)
131     abort ();
132   mpf_set_str (x, ".000000000000000000000000000000000000000123456@28", 16);
133   MPF_CHECK_FORMAT (x);
134   if (mpf_cmp (x, y) != 0)
135     abort ();
136   mpf_set_str (x, "00000000000000000000.00000000000000000000123456@15", 16);
137   MPF_CHECK_FORMAT (x);
138   if (mpf_cmp (x, y) != 0)
139     abort ();
140 
141   mpf_set_str (y, "   0", 10);
142   mpf_set_str (x, "00000000000000000000000000000000000000000000000000000", 10);
143   MPF_CHECK_FORMAT (x);
144   if (mpf_cmp (x, y) != 0)
145     abort ();
146   mpf_set_str (x, "0000000000000000000000000000000000000000000000000000.", 10);
147   MPF_CHECK_FORMAT (x);
148   if (mpf_cmp (x, y) != 0)
149     abort ();
150   mpf_set_str (x, "000000000000000000000000000000000000000000000000000.0", 10);
151   MPF_CHECK_FORMAT (x);
152   if (mpf_cmp (x, y) != 0)
153     abort ();
154   mpf_set_str (x, ".0000000000000000000000000000000000000000000000000000", 10);
155   MPF_CHECK_FORMAT (x);
156   if (mpf_cmp (x, y) != 0)
157     abort ();
158   mpf_set_str (x, "0.000000000000000000000000000000000000000000000000000", 10);
159   MPF_CHECK_FORMAT (x);
160   if (mpf_cmp (x, y) != 0)
161     abort ();
162 
163   mpf_set_str (x, "00000000000000000000000000000000000000000000000000000", 16);
164   MPF_CHECK_FORMAT (x);
165   if (mpf_cmp (x, y) != 0)
166     abort ();
167   mpf_set_str (x, "0000000000000000000000000000000000000000000000000000.", 16);
168   MPF_CHECK_FORMAT (x);
169   if (mpf_cmp (x, y) != 0)
170     abort ();
171   mpf_set_str (x, "000000000000000000000000000000000000000000000000000.0", 16);
172   MPF_CHECK_FORMAT (x);
173   if (mpf_cmp (x, y) != 0)
174     abort ();
175   mpf_set_str (x, ".0000000000000000000000000000000000000000000000000000", 16);
176   MPF_CHECK_FORMAT (x);
177   if (mpf_cmp (x, y) != 0)
178     abort ();
179   mpf_set_str (x, "0.000000000000000000000000000000000000000000000000000", 16);
180   MPF_CHECK_FORMAT (x);
181   if (mpf_cmp (x, y) != 0)
182     abort ();
183   mpf_set_str (x, "+00000000000000000000000000000000000000000000000000000e-345", 9);
184   MPF_CHECK_FORMAT (x);
185   if (mpf_cmp (x, y) != 0)
186     abort ();
187   mpf_set_str (x, "-0000000000000000000000000000000000000000000000000000.@AB", 26);
188   MPF_CHECK_FORMAT (x);
189   if (mpf_cmp (x, y) != 0)
190     abort ();
191   mpf_set_str (x, "000000000000000000000000000000000000000000000000000.0@78", 19);
192   MPF_CHECK_FORMAT (x);
193   if (mpf_cmp (x, y) != 0)
194     abort ();
195   mpf_set_str (x, "+.0000000000000000000000000000000000000000000000000000e555", 6);
196   MPF_CHECK_FORMAT (x);
197   if (mpf_cmp (x, y) != 0)
198     abort ();
199   mpf_set_str (x, "-0.000000000000000000000000000000000000000000000000000@-AAAAAAAAAAAAAAAAAAAAAAAA", 17);
200   MPF_CHECK_FORMAT (x);
201   if (mpf_cmp (x, y) != 0)
202     abort ();
203 
204   /* Now test random values.  */
205 
206   for (i = 0; i < reps; i++)
207     {
208       if (i == 0)
209         {
210           /* exercise the special case in get_str for for x==0 */
211           mpf_set_ui (x, 0L);
212           base = 0;
213         }
214       else
215         {
216           size = urandom () % (2 * SIZE) - SIZE;
217           exp = urandom () % EXPO;
218           mpf_random2 (x, size, exp);
219           base = urandom () % 62;
220           base += base > 0;
221         }
222 
223       str = mpf_get_str (0, &bexp, base, 0, x);
224 
225       if (str[0] == '-')
226 	sprintf (buf, "-0.%s@%ld", str + 1, bexp);
227       else
228 	sprintf (buf, "0.%s@%ld", str, bexp);
229 
230       mpf_set_str_or_abort (y, buf, -base);
231       (*__gmp_free_func) (str, strlen (str) + 1);
232 
233       mpf_reldiff (rerr, x, y);
234       if (mpf_cmp (rerr, max_rerr) > 0)
235 	{
236 	  mpf_set (max_rerr, rerr);
237 #if VERBOSE
238 	  mpf_dump (max_rerr);
239 #endif
240 	  if (mpf_cmp (rerr, limit_rerr) > 0)
241 	    {
242 	      printf ("ERROR after %d tests\n", i);
243 	      printf ("base = %d\n", base);
244 	      printf ("   x = "); mpf_dump (x);
245 	      printf ("   y = "); mpf_dump (y);
246 	      abort ();
247 	    }
248 	}
249     }
250 
251   mpf_clear (limit_rerr);
252   mpf_clear (rerr);
253   mpf_clear (max_rerr);
254 
255   mpf_clear (x);
256   mpf_clear (y);
257   mpf_clear (d);
258 
259   tests_end ();
260   exit (0);
261 }
262