(root)/
gmp-6.3.0/
demos/
expr/
t-expr.c
       1  /* Test expression evaluation (print nothing and exit 0 if successful).
       2  
       3  Copyright 2000-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 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  
      14  or
      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  
      20  or both in parallel, as here.
      21  
      22  The GNU MP Library is distributed in the hope that it will be useful, but
      23  WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
      24  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      25  for more details.
      26  
      27  You should have received copies of the GNU General Public License and the
      28  GNU Lesser General Public License along with the GNU MP Library.  If not,
      29  see 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  
      39  int  option_trace = 0;
      40  
      41  
      42  struct 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  
      54  struct 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  
     136  const 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  
     184  const struct data_t  data_zq[] = {
     185    /* expecting failure */
     186    { 0, "1.2", NULL },
     187  };
     188  
     189  const 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  
     195  const 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  
     202  const 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  
     247  struct datalist_t {
     248    const struct data_t  *data;
     249    int                  num;
     250  };
     251  
     252  #define DATALIST(data)  { data, numberof (data) }
     253  
     254  struct datalist_t  list_z[] = {
     255    DATALIST (data_z),
     256    DATALIST (data_zq),
     257    DATALIST (data_zf),
     258    DATALIST (data_zqf),
     259  };
     260  
     261  struct datalist_t  list_q[] = {
     262    DATALIST (data_q),
     263    DATALIST (data_zq),
     264    DATALIST (data_zqf),
     265  };
     266  
     267  struct datalist_t  list_f[] = {
     268    DATALIST (data_zf),
     269    DATALIST (data_zqf),
     270    DATALIST (data_f),
     271  };
     272  
     273  
     274  void
     275  check_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  
     345  void
     346  check_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  
     421  void
     422  check_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  
     496  int
     497  main (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  }