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

数学计算

开发平台:

Unix_Linux

  1. /* mpq expression evaluation
  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 <stdio.h>
  15. #include <string.h>
  16. #include "gmp.h"
  17. #include "expr-impl.h"
  18. /* Change this to "#define TRACE(x) x" to get some traces. */
  19. #define TRACE(x)
  20. static void
  21. e_mpq_pow_ui (mpq_ptr r, mpq_srcptr b, unsigned long e)
  22. {
  23.   mpz_pow_ui (mpq_numref(r), mpq_numref(b), e);
  24.   mpz_pow_ui (mpq_denref(r), mpq_denref(b), e);
  25. }
  26. /* Wrapped because mpq_sgn is a macro. */
  27. static int
  28. e_mpq_sgn (mpq_srcptr x)
  29. {
  30.   return mpq_sgn (x);
  31. }
  32. /* Wrapped because mpq_equal only guarantees a non-zero return, whereas we
  33.    want 1 or 0 for == and !=. */
  34. static int
  35. e_mpq_equal (mpq_srcptr x, mpq_srcptr y)
  36. {
  37.   return mpq_equal (x, y) != 0;
  38. }
  39. static int
  40. e_mpq_notequal (mpq_srcptr x, mpq_srcptr y)
  41. {
  42.   return ! mpq_equal (x, y);
  43. }
  44. static void
  45. e_mpq_num (mpq_ptr w, mpq_srcptr x)
  46. {
  47.   if (w != x)
  48.     mpz_set (mpq_numref(w), mpq_numref(x));
  49.   mpz_set_ui (mpq_denref(w), 1L);
  50. }
  51. static void
  52. e_mpq_den (mpq_ptr w, mpq_srcptr x)
  53. {
  54.   if (w == x)
  55.     mpz_swap (mpq_numref(w), mpq_denref(w));
  56.   else
  57.     mpz_set (mpq_numref(w), mpq_denref(x));
  58.   mpz_set_ui (mpq_denref(w), 1L);
  59. }
  60. static __gmp_const struct mpexpr_operator_t  _mpq_expr_standard_table[] = {
  61.   { "**",  (mpexpr_fun_t) e_mpq_pow_ui,
  62.     MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC,                   220 },
  63.   { "!",   (mpexpr_fun_t) e_mpq_sgn,
  64.     MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX,                     210 },
  65.   { "-",   (mpexpr_fun_t) mpq_neg,
  66.     MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX,                           210 },
  67.   { "*",   (mpexpr_fun_t) mpq_mul,           MPEXPR_TYPE_BINARY,      200 },
  68.   { "/",   (mpexpr_fun_t) mpq_div,           MPEXPR_TYPE_BINARY,      200 },
  69.   { "+",   (mpexpr_fun_t) mpq_add,           MPEXPR_TYPE_BINARY,      190 },
  70.   { "-",   (mpexpr_fun_t) mpq_sub,           MPEXPR_TYPE_BINARY,      190 },
  71.   { "<<",  (mpexpr_fun_t) mpq_mul_2exp,      MPEXPR_TYPE_BINARY_UI,   180 },
  72.   { ">>",  (mpexpr_fun_t) mpq_div_2exp,      MPEXPR_TYPE_BINARY_UI,   180 },
  73.   { "<=",  (mpexpr_fun_t) mpq_cmp,           MPEXPR_TYPE_CMP_LE,      170 },
  74.   { "<",   (mpexpr_fun_t) mpq_cmp,           MPEXPR_TYPE_CMP_LT,      170 },
  75.   { ">=",  (mpexpr_fun_t) mpq_cmp,           MPEXPR_TYPE_CMP_GE,      170 },
  76.   { ">",   (mpexpr_fun_t) mpq_cmp,           MPEXPR_TYPE_CMP_GT,      170 },
  77.   { "==",  (mpexpr_fun_t) e_mpq_equal,       MPEXPR_TYPE_I_BINARY,    160 },
  78.   { "!=",  (mpexpr_fun_t) e_mpq_notequal,    MPEXPR_TYPE_I_BINARY,    160 },
  79.   { "&&",  (mpexpr_fun_t) e_mpq_sgn,         MPEXPR_TYPE_LOGICAL_AND, 120 },
  80.   { "||",  (mpexpr_fun_t) e_mpq_sgn,         MPEXPR_TYPE_LOGICAL_OR,  110 },
  81.   { ":",   NULL,                             MPEXPR_TYPE_COLON,       101 },
  82.   { "?",   (mpexpr_fun_t) e_mpq_sgn,         MPEXPR_TYPE_QUESTION,    100 },
  83.   { ")",   (mpexpr_fun_t) e_mpq_sgn,         MPEXPR_TYPE_CLOSEPAREN,    4 },
  84.   { "(",   (mpexpr_fun_t) e_mpq_sgn,         MPEXPR_TYPE_OPENPAREN,     3 },
  85.   { ",",   (mpexpr_fun_t) e_mpq_sgn,         MPEXPR_TYPE_ARGSEP,        2 },
  86.   { "$",   NULL,                             MPEXPR_TYPE_VARIABLE,      1 },
  87.   { "abs",  (mpexpr_fun_t) mpq_abs,          MPEXPR_TYPE_UNARY            },
  88.   { "cmp",  (mpexpr_fun_t) mpq_cmp,          MPEXPR_TYPE_I_BINARY         },
  89.   { "den",  (mpexpr_fun_t) e_mpq_den,        MPEXPR_TYPE_UNARY            },
  90.   { "max",  (mpexpr_fun_t) mpq_cmp,  MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
  91.   { "min",  (mpexpr_fun_t) mpq_cmp,  MPEXPR_TYPE_MIN | MPEXPR_TYPE_PAIRWISE },
  92.   { "num",  (mpexpr_fun_t) e_mpq_num,        MPEXPR_TYPE_UNARY            },
  93.   { "sgn",  (mpexpr_fun_t) e_mpq_sgn,        MPEXPR_TYPE_I_UNARY          },
  94.   { NULL }
  95. };
  96. __gmp_const struct mpexpr_operator_t * __gmp_const mpq_expr_standard_table
  97. = _mpq_expr_standard_table;
  98. int
  99. #if HAVE_STDARG
  100. mpq_expr (mpq_ptr res, int base, __gmp_const char *e, ...)
  101. #else
  102. mpq_expr (va_alist)
  103.      va_dcl
  104. #endif
  105. {
  106.   mpq_srcptr  var[MPEXPR_VARIABLES];
  107.   va_list     ap;
  108.   int         ret;
  109. #if HAVE_STDARG
  110.   va_start (ap, e);
  111. #else
  112.   mpq_ptr           res;
  113.   int               base;
  114.   __gmp_const char  *e;
  115.   va_start (ap);
  116.   res  = va_arg (ap, mpq_ptr);
  117.   base = va_arg (ap, int);
  118.   e    = va_arg (ap, __gmp_const char *);
  119. #endif
  120.   TRACE (printf ("mpq_expr(): base %d, %sn", base, e));
  121.   ret = mpexpr_va_to_var ((void **) var, ap);
  122.   va_end (ap);
  123.   if (ret != MPEXPR_RESULT_OK)
  124.     return ret;
  125.   return mpq_expr_a (mpq_expr_standard_table, res, base, e, strlen(e), var);
  126. }