t-expr.c
上传用户:qaz666999
上传日期:2022-08-06
资源大小:2570k
文件大小:12k
源码类别:

数学计算

开发平台:

Unix_Linux

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