Annotation of OpenXM_contrib/gmp/demos/expr/exprfa.c, Revision 1.1
1.1 ! ohara 1: /* mpf expression evaluation */
! 2:
! 3: /*
! 4: Copyright 2000, 2001 Free Software Foundation, Inc.
! 5:
! 6: This file is part of the GNU MP Library.
! 7:
! 8: The GNU MP Library is free software; you can redistribute it and/or modify
! 9: it under the terms of the GNU Lesser General Public License as published by
! 10: the Free Software Foundation; either version 2.1 of the License, or (at your
! 11: option) any later version.
! 12:
! 13: The GNU MP Library is distributed in the hope that it will be useful, but
! 14: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 15: or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
! 16: License for more details.
! 17:
! 18: You should have received a copy of the GNU Lesser General Public License
! 19: along with the GNU MP Library; see the file COPYING.LIB. If not, write to
! 20: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
! 21: MA 02111-1307, USA.
! 22: */
! 23:
! 24: /* Future: Bitwise "&", "|" and "&" could be done, if desired. Not sure
! 25: those functions would be much value though. */
! 26:
! 27:
! 28: #include <ctype.h>
! 29: #include <stdio.h>
! 30:
! 31: #include "gmp.h"
! 32: #include "expr-impl.h"
! 33:
! 34:
! 35: /* Change this to "#define TRACE(x) x" to get some traces. */
! 36: #define TRACE(x)
! 37:
! 38:
! 39: static size_t
! 40: e_mpf_number (mpf_ptr res, __gmp_const char *e, size_t elen, int base)
! 41: {
! 42: char *edup;
! 43: size_t i, ret, extra=0;
! 44: int mant_base, exp_base;
! 45:
! 46: TRACE (printf ("mpf_number base=%d \"%.*s\"\n", base, (int) elen, e));
! 47:
! 48: /* mpf_set_str doesn't currently accept 0x for hex in base==0, so do it
! 49: here instead. FIXME: Would prefer to let mpf_set_str handle this. */
! 50: if (base == 0 && elen >= 2 && e[0] == '0' && (e[1] == 'x' || e[1] == 'X'))
! 51: {
! 52: base = 16;
! 53: extra = 2;
! 54: e += extra;
! 55: elen -= extra;
! 56: }
! 57:
! 58: if (base == 0)
! 59: mant_base = 10;
! 60: else if (base < 0)
! 61: mant_base = -base;
! 62: else
! 63: mant_base = base;
! 64:
! 65: /* exponent in decimal if base is negative */
! 66: if (base < 0)
! 67: exp_base = 10;
! 68: else if (base == 0)
! 69: exp_base = 10;
! 70: else
! 71: exp_base = base;
! 72:
! 73: #define IS_EXPONENT(c) \
! 74: (c == '@' || (base <= 10 && base >= -10 && (e[i] == 'e' || e[i] == 'E')))
! 75:
! 76: i = 0;
! 77: for (;;)
! 78: {
! 79: if (i >= elen)
! 80: goto parsed;
! 81: if (e[i] == '.')
! 82: break;
! 83: if (IS_EXPONENT (e[i]))
! 84: goto exponent;
! 85: if (! isasciidigit_in_base (e[i], mant_base))
! 86: goto parsed;
! 87: i++;
! 88: }
! 89:
! 90: /* fraction */
! 91: i++;
! 92: for (;;)
! 93: {
! 94: if (i >= elen)
! 95: goto parsed;
! 96: if (IS_EXPONENT (e[i]))
! 97: goto exponent;
! 98: if (! isasciidigit_in_base (e[i], mant_base))
! 99: goto parsed;
! 100: i++;
! 101: }
! 102:
! 103: exponent:
! 104: i++;
! 105: if (i >= elen)
! 106: goto parsed;
! 107: if (e[i] == '-')
! 108: i++;
! 109: for (;;)
! 110: {
! 111: if (i >= elen)
! 112: goto parsed;
! 113: if (! isasciidigit_in_base (e[i], exp_base))
! 114: break;
! 115: i++;
! 116: }
! 117:
! 118: parsed:
! 119: TRACE (printf (" parsed i=%u \"%.*s\"\n", i, (int) i, e));
! 120:
! 121: edup = (*__gmp_allocate_func) (i+1);
! 122: memcpy (edup, e, i);
! 123: edup[i] = '\0';
! 124:
! 125: if (mpf_set_str (res, edup, base) == 0)
! 126: ret = i + extra;
! 127: else
! 128: ret = 0;
! 129:
! 130: (*__gmp_free_func) (edup, i+1);
! 131: return ret;
! 132: }
! 133:
! 134: static int
! 135: e_mpf_ulong_p (mpf_srcptr f)
! 136: {
! 137: return mpf_integer_p (f) && mpf_fits_ulong_p (f);
! 138: }
! 139:
! 140: /* Don't want to change the precision of w, can only do an actual swap when
! 141: w and x have the same precision. */
! 142: static void
! 143: e_mpf_set_or_swap (mpf_ptr w, mpf_ptr x)
! 144: {
! 145: if (mpf_get_prec (w) == mpf_get_prec (x))
! 146: mpf_swap (w, x);
! 147: else
! 148: mpf_set (w, x);
! 149: }
! 150:
! 151:
! 152: int
! 153: mpf_expr_a (__gmp_const struct mpexpr_operator_t *table,
! 154: mpf_ptr res, int base, unsigned long prec,
! 155: __gmp_const char *e, size_t elen,
! 156: mpf_srcptr var[26])
! 157: {
! 158: struct mpexpr_parse_t p;
! 159:
! 160: p.table = table;
! 161: p.res = (mpX_ptr) res;
! 162: p.base = base;
! 163: p.prec = prec;
! 164: p.e = e;
! 165: p.elen = elen;
! 166: p.var = (mpX_srcptr *) var;
! 167:
! 168: p.mpX_clear = (mpexpr_fun_one_t) mpf_clear;
! 169: p.mpX_ulong_p = (mpexpr_fun_i_unary_t) e_mpf_ulong_p;
! 170: p.mpX_get_ui = (mpexpr_fun_get_ui_t) mpf_get_ui;
! 171: p.mpX_init = (mpexpr_fun_unary_ui_t) mpf_init;
! 172: p.mpX_number = (mpexpr_fun_number_t) e_mpf_number;
! 173: p.mpX_set = (mpexpr_fun_unary_t) mpf_set;
! 174: p.mpX_set_or_swap = (mpexpr_fun_unary_t) e_mpf_set_or_swap;
! 175: p.mpX_set_si = (mpexpr_fun_set_si_t) mpf_set_si;
! 176: p.mpX_swap = (mpexpr_fun_swap_t) mpf_swap;
! 177:
! 178: return mpexpr_evaluate (&p);
! 179: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>