blob: 64fbfaba1d540fd89551fb749d4b28451a888729 [file] [log] [blame]
Austin Schuhbb1338c2024-06-15 19:31:16 -07001/* Test expression evaluation (print nothing and exit 0 if successful).
2
3Copyright 2000-2004 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library.
6
7The GNU MP Library is free software; you can redistribute it and/or modify
8it under the terms of either:
9
10 * the GNU Lesser General Public License as published by the Free
11 Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
13
14or
15
16 * the GNU General Public License as published by the Free Software
17 Foundation; either version 2 of the License, or (at your option) any
18 later version.
19
20or both in parallel, as here.
21
22The GNU MP Library is distributed in the hope that it will be useful, but
23WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25for more details.
26
27You should have received copies of the GNU General Public License and the
28GNU Lesser General Public License along with the GNU MP Library. If not,
29see https://www.gnu.org/licenses/. */
30
31#include <stdio.h>
32#include <stdlib.h>
33
34#include "gmp-impl.h"
35#include "tests.h"
36#include "expr-impl.h"
37
38
39int option_trace = 0;
40
41
42struct data_t {
43 int base;
44 const char *expr;
45 const char *want;
46};
47
48#define numberof(x) (sizeof (x) / sizeof ((x)[0]))
49
50
51/* These data_xxx[] arrays are tables to be tested with one or more of the
52 mp?_t types. z=mpz_t, q=mpz_t, f=mpf_t. */
53
54struct data_t data_zqf[] = {
55
56 /* various deliberately wrong expressions */
57 { 0, "", NULL },
58 { 0, "1+", NULL },
59 { 0, "+2", NULL },
60 { 0, "1,2", NULL },
61 { 0, "foo(1,2)", NULL },
62 { 0, "1+foo", NULL },
63 { 10, "0fff", NULL },
64 { 0, "!", NULL },
65 { 0, "10!", NULL },
66 { 0, "-10!", NULL },
67 { 0, "gcd((4,6))", NULL },
68 { 0, "()", NULL },
69 { 0, "fac(2**1000)", NULL },
70 { 0, "$", NULL },
71 { 0, "$-", NULL },
72
73 /* some basics */
74 { 10, "123", "123" },
75 { 10, "-123", "-123" },
76 { 10, "1+2", "3" },
77 { 10, "1+2+3", "6" },
78 { 10, "1+2*3", "7" },
79 { 10, "3*2+1", "7" },
80 { 10, "$a", "55" },
81 { 10, "b", "99" },
82 { 16, "b", "11" },
83 { 10, "4**3 * 2 + 1", "129" },
84 { 10, "1<2", "1" },
85 { 10, "1>2", "0" },
86
87 { 10, "(123)", "123" },
88
89 { 10, "sgn(-123)", "-1" },
90 { 10, "5-7", "-2" },
91
92 { 0, "cmp(0,0)", "0" },
93 { 0, "cmp(1,0)", "1" },
94 { 0, "cmp(0,1)", "-1" },
95 { 0, "cmp(-1,0)", "-1" },
96 { 0, "cmp(0,-1)", "1" },
97
98 { 10, "0 ? 123 : 456", "456" },
99 { 10, "1 ? 4+5 : 6+7", "9" },
100
101 { 10, "(123)", "123" },
102 { 10, "(2+3)", "5" },
103 { 10, "(4+5)*(5+6)", "99" },
104
105 { 0, "1 << 16", "65536" },
106 { 0, "256 >> 4", "16" },
107 { 0, "-256 >> 4", "-16" },
108
109 { 0, "!1", "0" },
110 { 0, "!9", "0" },
111 { 0, "!0", "1" },
112
113 { 0, "2**2**2", "16" },
114 { 0, "-2**2**2", "-16" },
115
116 { 0, "0x100", "256" },
117 { 10, "0x100", NULL },
118 { 10, "0x 100", NULL },
119
120 { 0, " max ( 1, 2, 3, 4, 5, 6, 7, 8)", "8" },
121 { 0, " max ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "9" },
122 { 0, " min ( 1, 9, 2, 3, 4, 5, 6, 7, 8)", "1" },
123
124 { 10, "abs(123)", "123" },
125 { 10, "abs(-123)", "123" },
126 { 10, "abs(0)", "0" },
127
128 /* filling data stack */
129 { 0, "1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+(1+1))))))))))))))", "16" },
130
131 /* filling control stack */
132 { 0, "----------------------------------------------------1", "1" },
133};
134
135
136const struct data_t data_z[] = {
137 { 0, "divisible_p(333,3)", "1" },
138 { 0, "congruent_p(7,1,3)", "1" },
139
140 { 0, "cmpabs(0,0)", "0" },
141 { 0, "cmpabs(1,0)", "1" },
142 { 0, "cmpabs(0,1)", "-1" },
143 { 0, "cmpabs(-1,0)", "1" },
144 { 0, "cmpabs(0,-1)", "-1" },
145
146 { 0, "odd_p(1)", "1" },
147 { 0, "odd_p(0)", "0" },
148 { 0, "odd_p(-1)", "1" },
149
150 { 0, "even_p(1)", "0" },
151 { 0, "even_p(0)", "1" },
152 { 0, "even_p(-1)", "0" },
153
154 { 0, "fac(0)", "1" },
155 { 0, "fac(1)", "1" },
156 { 0, "fac(2)", "2" },
157 { 0, "fac(3)", "6" },
158 { 0, "fac(10)", "3628800" },
159
160 { 10, "root(81,4)", "3" },
161
162 { 10, "gcd(4,6)", "2" },
163 { 10, "gcd(4,6,9)", "1" },
164
165 { 10, "powm(3,2,9)", "0" },
166 { 10, "powm(3,2,8)", "1" },
167
168 /* filling data stack */
169 { 0, "1 ? 1 : 1 || 1 && 1 | 1 ^ 1 & 1 == 1 >= 1 << 1 - 1 * 1 ** 1", "1" },
170
171 /* filling control stack */
172 { 0, "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~1", "1" },
173
174 { 0, "fib(10)", "55" },
175
176 { 0, "setbit(0,5)", "32" },
177 { 0, "clrbit(32,5)", "0" },
178 { 0, "tstbit(32,5)", "1" },
179 { 0, "tstbit(32,4)", "0" },
180 { 0, "scan0(7,0)", "3" },
181 { 0, "scan1(7,0)", "0" },
182};
183
184const struct data_t data_zq[] = {
185 /* expecting failure */
186 { 0, "1.2", NULL },
187};
188
189const struct data_t data_q[] = {
190 { 10, "(1/2 + 1/3 + 1/4 + 1/5 + 1/6)*20", "29" },
191 { 0, "num(5/9)", "5" },
192 { 0, "den(5/9)", "9" },
193};
194
195const struct data_t data_zf[] = {
196 { 10, "sqrt ( 49 )", "7" },
197 { 10, "sqrt ( 49 ) + 1", "8" },
198 { 10, "sqrt((49))", "7" },
199 { 10, "sqrt((((((((49))))))))", "7" },
200};
201
202const struct data_t data_f[] = {
203 { 0, "1@10", "10000000000" },
204 { 0, "1.5@10", "15000000000" },
205 { 0, "1000@-1", "100" },
206 { 0, "10.00@-1", "1" },
207
208 { 0, "1e10", "10000000000" },
209 { 0, "1.5e10", "15000000000" },
210 { 0, "1000e-1", "100" },
211 { 0, "10.00e-1", "1" },
212
213 { 16, "1@9", "68719476736" },
214
215 { 16, "1@10", "18446744073709551616" },
216 { -16, "1@10", "1099511627776" },
217
218 { 0, "ceil(0)", "0" },
219 { 0, "ceil(0.25)", "1" },
220 { 0, "ceil(0.5)", "1" },
221 { 0, "ceil(1.5)", "2" },
222 { 0, "ceil(-0.5)", "0" },
223 { 0, "ceil(-1.5)", "-1" },
224
225 /* only simple cases because mpf_eq currently only works on whole limbs */
226 { 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,64)", "1" },
227 { 0, "eq(0xFFFFFFFFFFFFFFFF1111111111111111,0xFFFFFFFFFFFFFFFF2222222222222222,128)", "0" },
228
229 { 0, "floor(0)", "0" },
230 { 0, "floor(0.25)", "0" },
231 { 0, "floor(0.5)", "0" },
232 { 0, "floor(1.5)", "1" },
233 { 0, "floor(-0.5)", "-1" },
234 { 0, "floor(-1.5)", "-2" },
235
236 { 0, "integer_p(1)", "1" },
237 { 0, "integer_p(0.5)", "0" },
238
239 { 0, "trunc(0)", "0" },
240 { 0, "trunc(0.25)", "0" },
241 { 0, "trunc(0.5)", "0" },
242 { 0, "trunc(1.5)", "1" },
243 { 0, "trunc(-0.5)", "0" },
244 { 0, "trunc(-1.5)", "-1" },
245};
246
247struct datalist_t {
248 const struct data_t *data;
249 int num;
250};
251
252#define DATALIST(data) { data, numberof (data) }
253
254struct datalist_t list_z[] = {
255 DATALIST (data_z),
256 DATALIST (data_zq),
257 DATALIST (data_zf),
258 DATALIST (data_zqf),
259};
260
261struct datalist_t list_q[] = {
262 DATALIST (data_q),
263 DATALIST (data_zq),
264 DATALIST (data_zqf),
265};
266
267struct datalist_t list_f[] = {
268 DATALIST (data_zf),
269 DATALIST (data_zqf),
270 DATALIST (data_f),
271};
272
273
274void
275check_z (void)
276{
277 const struct data_t *data;
278 mpz_t a, b, got, want;
279 int l, i, ret;
280
281 mpz_init (got);
282 mpz_init (want);
283 mpz_init_set_ui (a, 55);
284 mpz_init_set_ui (b, 99);
285
286 for (l = 0; l < numberof (list_z); l++)
287 {
288 data = list_z[l].data;
289
290 for (i = 0; i < list_z[l].num; i++)
291 {
292 if (option_trace)
293 printf ("mpz_expr \"%s\"\n", data[i].expr);
294
295 ret = mpz_expr (got, data[i].base, data[i].expr, a, b, NULL);
296
297 if (data[i].want == NULL)
298 {
299 /* expect to fail */
300 if (ret == MPEXPR_RESULT_OK)
301 {
302 printf ("mpz_expr wrong return value, got %d, expected failure\n", ret);
303 goto error;
304 }
305 }
306 else
307 {
308 if (mpz_set_str (want, data[i].want, 0) != 0)
309 {
310 printf ("Cannot parse wanted value string\n");
311 goto error;
312 }
313 if (ret != MPEXPR_RESULT_OK)
314 {
315 printf ("mpz_expr failed unexpectedly\n");
316 printf (" return value %d\n", ret);
317 goto error;
318 }
319 if (mpz_cmp (got, want) != 0)
320 {
321 printf ("mpz_expr wrong result\n");
322 printf (" got "); mpz_out_str (stdout, 10, got);
323 printf ("\n");
324 printf (" want "); mpz_out_str (stdout, 10, want);
325 printf ("\n");
326 goto error;
327 }
328 }
329 }
330 }
331 mpz_clear (a);
332 mpz_clear (b);
333 mpz_clear (got);
334 mpz_clear (want);
335 return;
336
337 error:
338 printf (" base %d\n", data[i].base);
339 printf (" expr \"%s\"\n", data[i].expr);
340 if (data[i].want != NULL)
341 printf (" want \"%s\"\n", data[i].want);
342 abort ();
343}
344
345void
346check_q (void)
347{
348 const struct data_t *data;
349 mpq_t a, b, got, want;
350 int l, i, ret;
351
352 mpq_init (got);
353 mpq_init (want);
354 mpq_init (a);
355 mpq_init (b);
356
357 mpq_set_ui (a, 55, 1);
358 mpq_set_ui (b, 99, 1);
359
360 for (l = 0; l < numberof (list_q); l++)
361 {
362 data = list_q[l].data;
363
364 for (i = 0; i < list_q[l].num; i++)
365 {
366 if (option_trace)
367 printf ("mpq_expr \"%s\"\n", data[i].expr);
368
369 ret = mpq_expr (got, data[i].base, data[i].expr, a, b, NULL);
370
371 if (data[i].want == NULL)
372 {
373 /* expect to fail */
374 if (ret == MPEXPR_RESULT_OK)
375 {
376 printf ("mpq_expr wrong return value, got %d, expected failure\n", ret);
377 goto error;
378 }
379 }
380 else
381 {
382 if (mpz_set_str (mpq_numref(want), data[i].want, 0) != 0)
383 {
384 printf ("Cannot parse wanted value string\n");
385 goto error;
386 }
387 mpz_set_ui (mpq_denref(want), 1);
388
389 if (ret != MPEXPR_RESULT_OK)
390 {
391 printf ("mpq_expr failed unexpectedly\n");
392 printf (" return value %d\n", ret);
393 goto error;
394 }
395 if (mpq_cmp (got, want) != 0)
396 {
397 printf ("mpq_expr wrong result\n");
398 printf (" got "); mpq_out_str (stdout, 10, got);
399 printf ("\n");
400 printf (" want "); mpq_out_str (stdout, 10, want);
401 printf ("\n");
402 goto error;
403 }
404 }
405 }
406 }
407 mpq_clear (a);
408 mpq_clear (b);
409 mpq_clear (got);
410 mpq_clear (want);
411 return;
412
413 error:
414 printf (" base %d\n", data[i].base);
415 printf (" expr \"%s\"\n", data[i].expr);
416 if (data[i].want != NULL)
417 printf (" want \"%s\"\n", data[i].want);
418 abort ();
419}
420
421void
422check_f (void)
423{
424 const struct data_t *data;
425 mpf_t a, b, got, want;
426 int l, i, ret;
427
428 mpf_set_default_prec (200L);
429
430 mpf_init (got);
431 mpf_init (want);
432 mpf_init_set_ui (a, 55);
433 mpf_init_set_ui (b, 99);
434
435 for (l = 0; l < numberof (list_f); l++)
436 {
437 data = list_f[l].data;
438
439 for (i = 0; i < list_f[l].num; i++)
440 {
441 if (option_trace)
442 printf ("mpf_expr \"%s\"\n", data[i].expr);
443
444 ret = mpf_expr (got, data[i].base, data[i].expr, a, b, NULL);
445
446 if (data[i].want == NULL)
447 {
448 /* expect to fail */
449 if (ret == MPEXPR_RESULT_OK)
450 {
451 printf ("mpf_expr wrong return value, got %d, expected failure\n", ret);
452 goto error;
453 }
454 }
455 else
456 {
457 if (mpf_set_str (want, data[i].want, 0) != 0)
458 {
459 printf ("Cannot parse wanted value string\n");
460 goto error;
461 }
462
463 if (ret != MPEXPR_RESULT_OK)
464 {
465 printf ("mpf_expr failed unexpectedly\n");
466 printf (" return value %d\n", ret);
467 goto error;
468 }
469 if (mpf_cmp (got, want) != 0)
470 {
471 printf ("mpf_expr wrong result\n");
472 printf (" got "); mpf_out_str (stdout, 10, 20, got);
473 printf ("\n");
474 printf (" want "); mpf_out_str (stdout, 10, 20, want);
475 printf ("\n");
476 goto error;
477 }
478 }
479 }
480 }
481 mpf_clear (a);
482 mpf_clear (b);
483 mpf_clear (got);
484 mpf_clear (want);
485 return;
486
487 error:
488 printf (" base %d\n", data[i].base);
489 printf (" expr \"%s\"\n", data[i].expr);
490 if (data[i].want != NULL)
491 printf (" want \"%s\"\n", data[i].want);
492 abort ();
493}
494
495
496int
497main (int argc, char *argv[])
498{
499 tests_start ();
500
501 if (argc >= 2)
502 option_trace = 1;
503
504 check_z ();
505 check_q ();
506 check_f ();
507
508 tests_end ();
509 exit (0);
510}