blob: a64e86fdd759d8bde27f9811b94ed70adc0a79ec [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/* Test mpf_get_str and mpf_set_str.
2
3Copyright 1996, 2000, 2001, 2008, 2019 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the 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
35int
36main (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 (y, "0", 16);
164 mpf_set_str (x, "00000000000000000000000000000000000000000000000000000", 16);
165 MPF_CHECK_FORMAT (x);
166 if (mpf_cmp (x, y) != 0)
167 abort ();
168 mpf_set_str (x, "0000000000000000000000000000000000000000000000000000.", 16);
169 MPF_CHECK_FORMAT (x);
170 if (mpf_cmp (x, y) != 0)
171 abort ();
172 mpf_set_str (x, "000000000000000000000000000000000000000000000000000.0", 16);
173 MPF_CHECK_FORMAT (x);
174 if (mpf_cmp (x, y) != 0)
175 abort ();
176 mpf_set_str (x, ".0000000000000000000000000000000000000000000000000000", 16);
177 MPF_CHECK_FORMAT (x);
178 if (mpf_cmp (x, y) != 0)
179 abort ();
180 mpf_set_str (x, "0.000000000000000000000000000000000000000000000000000", 16);
181 MPF_CHECK_FORMAT (x);
182 if (mpf_cmp (x, y) != 0)
183 abort ();
184
185 /* Now test random values. */
186
187 for (i = 0; i < reps; i++)
188 {
189 if (i == 0)
190 {
191 /* exercise the special case in get_str for for x==0 */
192 mpf_set_ui (x, 0L);
193 base = 0;
194 }
195 else
196 {
197 size = urandom () % (2 * SIZE) - SIZE;
198 exp = urandom () % EXPO;
199 mpf_random2 (x, size, exp);
200 base = urandom () % 62;
201 base += base > 0;
202 }
203
204 str = mpf_get_str (0, &bexp, base, 0, x);
205
206 if (str[0] == '-')
207 sprintf (buf, "-0.%s@%ld", str + 1, bexp);
208 else
209 sprintf (buf, "0.%s@%ld", str, bexp);
210
211 mpf_set_str_or_abort (y, buf, -base);
212 (*__gmp_free_func) (str, strlen (str) + 1);
213
214 mpf_reldiff (rerr, x, y);
215 if (mpf_cmp (rerr, max_rerr) > 0)
216 {
217 mpf_set (max_rerr, rerr);
218#if VERBOSE
219 mpf_dump (max_rerr);
220#endif
221 if (mpf_cmp (rerr, limit_rerr) > 0)
222 {
223 printf ("ERROR after %d tests\n", i);
224 printf ("base = %d\n", base);
225 printf (" x = "); mpf_dump (x);
226 printf (" y = "); mpf_dump (y);
227 abort ();
228 }
229 }
230 }
231
232 mpf_clear (limit_rerr);
233 mpf_clear (rerr);
234 mpf_clear (max_rerr);
235
236 mpf_clear (x);
237 mpf_clear (y);
238 mpf_clear (d);
239
240 tests_end ();
241 exit (0);
242}