[BACK]Return to exprfa.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / demos / expr

Annotation of OpenXM_contrib/gmp/demos/expr/exprfa.c, Revision 1.1.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>