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