1 /* mpq expression evaluation
3 Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
5 This file is part of the GNU MP Library.
7 The GNU MP Library is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
12 The GNU MP Library is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
23 #include "expr-impl.h"
26 /* Change this to "#define TRACE(x) x" to get some traces. */
31 e_mpq_pow_ui (mpq_ptr r, mpq_srcptr b, unsigned long e)
33 mpz_pow_ui (mpq_numref(r), mpq_numref(b), e);
34 mpz_pow_ui (mpq_denref(r), mpq_denref(b), e);
37 /* Wrapped because mpq_sgn is a macro. */
39 e_mpq_sgn (mpq_srcptr x)
44 /* Wrapped because mpq_equal only guarantees a non-zero return, whereas we
45 want 1 or 0 for == and !=. */
47 e_mpq_equal (mpq_srcptr x, mpq_srcptr y)
49 return mpq_equal (x, y) != 0;
52 e_mpq_notequal (mpq_srcptr x, mpq_srcptr y)
54 return ! mpq_equal (x, y);
58 e_mpq_num (mpq_ptr w, mpq_srcptr x)
61 mpz_set (mpq_numref(w), mpq_numref(x));
62 mpz_set_ui (mpq_denref(w), 1L);
65 e_mpq_den (mpq_ptr w, mpq_srcptr x)
68 mpz_swap (mpq_numref(w), mpq_denref(w));
70 mpz_set (mpq_numref(w), mpq_denref(x));
71 mpz_set_ui (mpq_denref(w), 1L);
75 static __gmp_const struct mpexpr_operator_t _mpq_expr_standard_table[] = {
77 { "**", (mpexpr_fun_t) e_mpq_pow_ui,
78 MPEXPR_TYPE_BINARY_UI | MPEXPR_TYPE_RIGHTASSOC, 220 },
80 { "!", (mpexpr_fun_t) e_mpq_sgn,
81 MPEXPR_TYPE_LOGICAL_NOT | MPEXPR_TYPE_PREFIX, 210 },
82 { "-", (mpexpr_fun_t) mpq_neg,
83 MPEXPR_TYPE_UNARY | MPEXPR_TYPE_PREFIX, 210 },
85 { "*", (mpexpr_fun_t) mpq_mul, MPEXPR_TYPE_BINARY, 200 },
86 { "/", (mpexpr_fun_t) mpq_div, MPEXPR_TYPE_BINARY, 200 },
88 { "+", (mpexpr_fun_t) mpq_add, MPEXPR_TYPE_BINARY, 190 },
89 { "-", (mpexpr_fun_t) mpq_sub, MPEXPR_TYPE_BINARY, 190 },
91 { "<<", (mpexpr_fun_t) mpq_mul_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
92 { ">>", (mpexpr_fun_t) mpq_div_2exp, MPEXPR_TYPE_BINARY_UI, 180 },
94 { "<=", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_LE, 170 },
95 { "<", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_LT, 170 },
96 { ">=", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_GE, 170 },
97 { ">", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_CMP_GT, 170 },
99 { "==", (mpexpr_fun_t) e_mpq_equal, MPEXPR_TYPE_I_BINARY, 160 },
100 { "!=", (mpexpr_fun_t) e_mpq_notequal, MPEXPR_TYPE_I_BINARY, 160 },
102 { "&&", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_LOGICAL_AND, 120 },
103 { "||", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_LOGICAL_OR, 110 },
105 { ":", NULL, MPEXPR_TYPE_COLON, 101 },
106 { "?", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_QUESTION, 100 },
108 { ")", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_CLOSEPAREN, 4 },
109 { "(", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_OPENPAREN, 3 },
110 { ",", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_ARGSEP, 2 },
111 { "$", NULL, MPEXPR_TYPE_VARIABLE, 1 },
113 { "abs", (mpexpr_fun_t) mpq_abs, MPEXPR_TYPE_UNARY },
114 { "cmp", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_I_BINARY },
115 { "den", (mpexpr_fun_t) e_mpq_den, MPEXPR_TYPE_UNARY },
116 { "max", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_MAX | MPEXPR_TYPE_PAIRWISE },
117 { "min", (mpexpr_fun_t) mpq_cmp, MPEXPR_TYPE_MIN | MPEXPR_TYPE_PAIRWISE },
118 { "num", (mpexpr_fun_t) e_mpq_num, MPEXPR_TYPE_UNARY },
119 { "sgn", (mpexpr_fun_t) e_mpq_sgn, MPEXPR_TYPE_I_UNARY },
124 __gmp_const struct mpexpr_operator_t * __gmp_const mpq_expr_standard_table
125 = _mpq_expr_standard_table;
130 mpq_expr (mpq_ptr res, int base, __gmp_const char *e, ...)
136 mpq_srcptr var[MPEXPR_VARIABLES];
146 res = va_arg (ap, mpq_ptr);
147 base = va_arg (ap, int);
148 e = va_arg (ap, __gmp_const char *);
151 TRACE (printf ("mpq_expr(): base %d, %s\n", base, e));
152 ret = mpexpr_va_to_var ((void **) var, ap);
155 if (ret != MPEXPR_RESULT_OK)
158 return mpq_expr_a (mpq_expr_standard_table, res, base, e, strlen(e), var);