github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/demos/expr/t-expr.c (about)

     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.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  }