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

数学计算

开发平台:

Unix_Linux

  1. /* mpz expression evaluation, simple part
  2. Copyright 2000, 2001, 2002 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 <ctype.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include "gmp.h"
  18. #include "expr-impl.h"
  19. /* Change this to "#define TRACE(x) x" to get some traces. */
  20. #define TRACE(x)
  21. /* These are macros, so need function wrappers. */
  22. static int
  23. e_mpz_sgn (mpz_srcptr x)
  24. {
  25.   return mpz_sgn (x);
  26. }
  27. static int
  28. e_mpz_odd_p (mpz_srcptr x)
  29. {
  30.   return mpz_odd_p (x);
  31. }
  32. static int
  33. e_mpz_even_p (mpz_srcptr x)
  34. {
  35.   return mpz_even_p (x);
  36. }
  37. /* These wrapped because MPEXPR_TYPE_I_ functions are expected to return
  38.    "int" whereas these return "unsigned long".  */
  39. static void
  40. e_mpz_hamdist (mpz_ptr w, mpz_srcptr x, mpz_srcptr y)
  41. {
  42.   mpz_set_ui (w, mpz_hamdist (x, y));
  43. }
  44. static void
  45. e_mpz_popcount (mpz_ptr w, mpz_srcptr x)
  46. {
  47.   mpz_set_ui (w, mpz_popcount (x));
  48. }
  49. static void
  50. e_mpz_scan0 (mpz_ptr w, mpz_srcptr x, unsigned long start)
  51. {
  52.   mpz_set_ui (w, mpz_scan0 (x, start));
  53. }
  54. static void
  55. e_mpz_scan1 (mpz_ptr w, mpz_srcptr x, unsigned long start)
  56. {
  57.   mpz_set_ui (w, mpz_scan1 (x, start));
  58. }
  59. /* These wrapped because they're in-place whereas MPEXPR_TYPE_BINARY_UI
  60.    expects a separate source and destination.  Actually the parser will
  61.    normally pass w==x anyway.  */
  62. static void
  63. e_mpz_setbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
  64. {
  65.   if (w != x)
  66.     mpz_set (w, x);
  67.   mpz_setbit (w, n);
  68. }
  69. static void
  70. e_mpz_clrbit (mpz_ptr w, mpz_srcptr x, unsigned long n)
  71. {
  72.   if (w != x)
  73.     mpz_set (w, x);
  74.   mpz_clrbit (w, n);
  75. }
  76. static __gmp_const struct mpexpr_operator_t  _mpz_expr_standard_table[] = {
  77.   { "**",  (mpexpr_fun_t) mpz_pow_ui,
  78.     MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC,                  220 },
  79.   { "~",   (mpexpr_fun_t) mpz_com,
  80.     MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX,                          210 },
  81.   { "!",   (mpexpr_fun_t) e_mpz_sgn,
  82.     MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX,                    210 },
  83.   { "-",   (mpexpr_fun_t) mpz_neg,
  84.     MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX,                          210 },
  85.   { "*",   (mpexpr_fun_t) mpz_mul,          MPEXPR_TYPE_BINARY,      200 },
  86.   { "/",   (mpexpr_fun_t) mpz_tdiv_q,       MPEXPR_TYPE_BINARY,      200 },
  87.   { "%",   (mpexpr_fun_t) mpz_tdiv_r,       MPEXPR_TYPE_BINARY,      200 },
  88.   { "+",   (mpexpr_fun_t) mpz_add,          MPEXPR_TYPE_BINARY,      190 },
  89.   { "-",   (mpexpr_fun_t) mpz_sub,          MPEXPR_TYPE_BINARY,      190 },
  90.   { "<<",  (mpexpr_fun_t) mpz_mul_2exp,     MPEXPR_TYPE_BINARY_UI,   180 },
  91.   { ">>",  (mpexpr_fun_t) mpz_tdiv_q_2exp,  MPEXPR_TYPE_BINARY_UI,   180 },
  92.   { "<=",  (mpexpr_fun_t) mpz_cmp,          MPEXPR_TYPE_CMP_LE,      170 },
  93.   { "<",   (mpexpr_fun_t) mpz_cmp,          MPEXPR_TYPE_CMP_LT,      170 },
  94.   { ">=",  (mpexpr_fun_t) mpz_cmp,          MPEXPR_TYPE_CMP_GE,      170 },
  95.   { ">",   (mpexpr_fun_t) mpz_cmp,          MPEXPR_TYPE_CMP_GT,      170 },
  96.   { "==",  (mpexpr_fun_t) mpz_cmp,          MPEXPR_TYPE_CMP_EQ,      160 },
  97.   { "!=",  (mpexpr_fun_t) mpz_cmp,          MPEXPR_TYPE_CMP_NE,      160 },
  98.   { "&",   (mpexpr_fun_t) mpz_and,          MPEXPR_TYPE_BINARY,      150 },
  99.   { "^",   (mpexpr_fun_t) mpz_xor,          MPEXPR_TYPE_BINARY,      140 },
  100.   { "|",   (mpexpr_fun_t) mpz_ior,          MPEXPR_TYPE_BINARY,      130 },
  101.   { "&&",  (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
  102.   { "||",  (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_LOGICAL_OR,  110 },
  103.   { ":",   NULL,                            MPEXPR_TYPE_COLON,       101 },
  104.   { "?",   (mpexpr_fun_t) e_mpz_sgn, MPEXPR_TYPE_QUESTION,    100 },
  105.   { ")",   NULL,                            MPEXPR_TYPE_CLOSEPAREN,   4 },
  106.   { "(",   NULL,                            MPEXPR_TYPE_OPENPAREN,    3 },
  107.   { ",",   NULL,                            MPEXPR_TYPE_ARGSEP,       2 },
  108.   { "$",   NULL,                            MPEXPR_TYPE_VARIABLE,     1 },
  109.   { "abs",       (mpexpr_fun_t) mpz_abs,           MPEXPR_TYPE_UNARY         },
  110.   { "bin",       (mpexpr_fun_t) mpz_bin_ui,        MPEXPR_TYPE_BINARY_UI     },
  111.   { "clrbit",    (mpexpr_fun_t) e_mpz_clrbit,      MPEXPR_TYPE_BINARY_UI     },
  112.   { "cmp",       (mpexpr_fun_t) mpz_cmp,           MPEXPR_TYPE_I_BINARY      },
  113.   { "cmpabs",    (mpexpr_fun_t) mpz_cmpabs,        MPEXPR_TYPE_I_BINARY      },
  114.   { "congruent_p",(mpexpr_fun_t)mpz_congruent_p,   MPEXPR_TYPE_I_TERNARY     },
  115.   { "divisible_p",(mpexpr_fun_t)mpz_divisible_p,   MPEXPR_TYPE_I_BINARY      },
  116.   { "even_p",    (mpexpr_fun_t) e_mpz_even_p,      MPEXPR_TYPE_I_UNARY       },
  117.   { "fib",       (mpexpr_fun_t) mpz_fib_ui,        MPEXPR_TYPE_UNARY_UI      },
  118.   { "fac",       (mpexpr_fun_t) mpz_fac_ui,        MPEXPR_TYPE_UNARY_UI      },
  119.   { "gcd",       (mpexpr_fun_t) mpz_gcd,           MPEXPR_TYPE_BINARY
  120.    | MPEXPR_TYPE_PAIRWISE    },
  121.   { "hamdist",   (mpexpr_fun_t) e_mpz_hamdist,     MPEXPR_TYPE_BINARY        },
  122.   { "invert",    (mpexpr_fun_t) mpz_invert,        MPEXPR_TYPE_BINARY        },
  123.   { "jacobi",    (mpexpr_fun_t) mpz_jacobi,        MPEXPR_TYPE_I_BINARY      },
  124.   { "kronecker", (mpexpr_fun_t) mpz_kronecker,     MPEXPR_TYPE_I_BINARY      },
  125.   { "lcm",       (mpexpr_fun_t) mpz_lcm,           MPEXPR_TYPE_BINARY
  126.    | MPEXPR_TYPE_PAIRWISE    },
  127.   { "lucnum",    (mpexpr_fun_t) mpz_lucnum_ui,     MPEXPR_TYPE_UNARY_UI      },
  128.   { "max",       (mpexpr_fun_t) mpz_cmp,           MPEXPR_TYPE_MAX
  129.    | MPEXPR_TYPE_PAIRWISE    },
  130.   { "min",       (mpexpr_fun_t) mpz_cmp,           MPEXPR_TYPE_MIN
  131.    | MPEXPR_TYPE_PAIRWISE    },
  132.   { "nextprime", (mpexpr_fun_t) mpz_nextprime,     MPEXPR_TYPE_UNARY         },
  133.   { "odd_p",     (mpexpr_fun_t) e_mpz_odd_p,       MPEXPR_TYPE_I_UNARY       },
  134.   { "perfect_power_p", (mpexpr_fun_t)mpz_perfect_power_p, MPEXPR_TYPE_I_UNARY},
  135.   { "perfect_square_p",(mpexpr_fun_t)mpz_perfect_square_p,MPEXPR_TYPE_I_UNARY},
  136.   { "popcount",  (mpexpr_fun_t) e_mpz_popcount,    MPEXPR_TYPE_UNARY         },
  137.   { "powm",      (mpexpr_fun_t) mpz_powm,          MPEXPR_TYPE_TERNARY       },
  138.   { "probab_prime_p",  (mpexpr_fun_t)mpz_probab_prime_p,  MPEXPR_TYPE_I_UNARY},
  139.   { "root",      (mpexpr_fun_t) mpz_root,          MPEXPR_TYPE_BINARY_UI     },
  140.   { "scan0",     (mpexpr_fun_t) e_mpz_scan0,       MPEXPR_TYPE_BINARY_UI     },
  141.   { "scan1",     (mpexpr_fun_t) e_mpz_scan1,       MPEXPR_TYPE_BINARY_UI     },
  142.   { "setbit",    (mpexpr_fun_t) e_mpz_setbit,      MPEXPR_TYPE_BINARY_UI     },
  143.   { "tstbit",    (mpexpr_fun_t) mpz_tstbit,        MPEXPR_TYPE_I_BINARY_UI   },
  144.   { "sgn",       (mpexpr_fun_t) e_mpz_sgn,         MPEXPR_TYPE_I_UNARY       },
  145.   { "sqrt",      (mpexpr_fun_t) mpz_sqrt,          MPEXPR_TYPE_UNARY         },
  146.   { NULL }
  147. };
  148. /* The table is available globally only through a pointer, so the table size
  149.    can change without breaking binary compatibility. */
  150. __gmp_const struct mpexpr_operator_t * __gmp_const mpz_expr_standard_table
  151. = _mpz_expr_standard_table;
  152. int
  153. #if HAVE_STDARG
  154. mpz_expr (mpz_ptr res, int base, __gmp_const char *e, ...)
  155. #else
  156. mpz_expr (va_alist)
  157.      va_dcl
  158. #endif
  159. {
  160.   mpz_srcptr  var[MPEXPR_VARIABLES];
  161.   va_list     ap;
  162.   int         ret;
  163. #if HAVE_STDARG
  164.   va_start (ap, e);
  165. #else
  166.   mpz_ptr           res;
  167.   int               base;
  168.   __gmp_const char  *e;
  169.   va_start (ap);
  170.   res  = va_arg (ap, mpz_ptr);
  171.   base = va_arg (ap, int);
  172.   e    = va_arg (ap, __gmp_const char *);
  173. #endif
  174.   TRACE (printf ("mpz_expr(): base %d, %sn", base, e));
  175.   ret = mpexpr_va_to_var ((void **) var, ap);
  176.   va_end (ap);
  177.   if (ret != MPEXPR_RESULT_OK)
  178.     return ret;
  179.   return mpz_expr_a (mpz_expr_standard_table, res, base, e, strlen(e), var);
  180. }