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