[BACK]Return to set_str.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpfr

Annotation of OpenXM_contrib/gmp/mpfr/set_str.c, Revision 1.1

1.1     ! ohara       1: /* mpfr_set_str -- set a floating-point number from a string
        !             2:
        !             3: Copyright 2000, 2001, 2002 Free Software Foundation, Inc.
        !             4:
        !             5: This file is part of the MPFR Library.
        !             6:
        !             7: The MPFR 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 2.1 of the License, or (at your
        !            10: option) any later version.
        !            11:
        !            12: The MPFR 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.
        !            16:
        !            17: You should have received a copy of the GNU Lesser General Public License
        !            18: along with the MPFR Library; see the file COPYING.LIB.  If not, write to
        !            19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
        !            20: MA 02111-1307, USA. */
        !            21:
        !            22: #include <ctype.h>
        !            23: #include <stdio.h>
        !            24: #include <stdlib.h>
        !            25: #include <limits.h>
        !            26: #include <errno.h>
        !            27:
        !            28: #ifdef HAVE_STRCASECMP
        !            29: #include <string.h>
        !            30: #else
        !            31: int strcasecmp (const char *, const char *);
        !            32: #endif
        !            33:
        !            34: #include "gmp.h"
        !            35: #include "gmp-impl.h"
        !            36: #include "longlong.h"
        !            37: #include "mpfr.h"
        !            38: #include "mpfr-impl.h"
        !            39:
        !            40: int
        !            41: mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode)
        !            42: {
        !            43:   mpz_t mantissa;
        !            44:   int negative, inex;
        !            45:   long k = 0;
        !            46:   unsigned char c;
        !            47:   long e;
        !            48:   mp_prec_t q;
        !            49:   mpfr_t y, z;
        !            50:
        !            51:   if (base < 2 || base > 36)
        !            52:     return 1;
        !            53:
        !            54:   if (strcasecmp(str, "NaN") == 0)
        !            55:     {
        !            56:       MPFR_SET_NAN(x);
        !            57:       /* MPFR_RET_NAN not used as the return value isn't a ternary value */
        !            58:       __mpfr_flags |= MPFR_FLAGS_NAN;
        !            59:       return 0;
        !            60:     }
        !            61:
        !            62:   negative = *str == '-';
        !            63:   if (negative || *str == '+')
        !            64:     str++;
        !            65:
        !            66:   if (strcasecmp(str, "Inf") == 0)
        !            67:     {
        !            68:       MPFR_CLEAR_NAN(x);
        !            69:       MPFR_SET_INF(x);
        !            70:       if (negative)
        !            71:         MPFR_SET_NEG(x);
        !            72:       else
        !            73:         MPFR_SET_POS(x);
        !            74:       return 0;
        !            75:     }
        !            76:
        !            77:   mpz_init(mantissa);
        !            78:   mpz_set_ui(mantissa, 0);
        !            79:
        !            80:   while (*str == '0')
        !            81:     str++; /* skip initial zeros */
        !            82:
        !            83:   /* allowed characters are '0' to '0'+base-1 if base <= 10,
        !            84:      and '0' to '9' plus 'a' to 'a'+base-11 if 10 < base <= 36 */
        !            85:   while (c = *str,
        !            86:          (isdigit(c) && c < '0' + base) ||
        !            87:          (islower(c) && c < 'a'-10 + base))
        !            88:     {
        !            89:       str++;
        !            90:       mpz_mul_ui(mantissa, mantissa, base);
        !            91:       mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10));
        !            92:     }
        !            93:
        !            94:   /* k is the number of non-zero digits before the decimal point */
        !            95:
        !            96:   if (*str == '.')
        !            97:     {
        !            98:       str++;
        !            99:       while (c = *str,
        !           100:              (isdigit(c) && c < '0' + base) ||
        !           101:              (islower(c) && c < 'a'-10 + base))
        !           102:        {
        !           103:           if (k == LONG_MAX)
        !           104:             {
        !           105:               mpz_clear(mantissa);
        !           106:               return -1;
        !           107:             }
        !           108:          k++;
        !           109:          str++;
        !           110:           mpz_mul_ui(mantissa, mantissa, base);
        !           111:           mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10));
        !           112:        }
        !           113:     }
        !           114:
        !           115:   if (*str == '\0') /* no exponent */
        !           116:     {
        !           117:       e = -k;
        !           118:     }
        !           119:   else if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@')
        !           120:     {
        !           121:       char *endptr;
        !           122:
        !           123:       if (*++str == '\0') /* exponent character but no exponent */
        !           124:         {
        !           125:           mpz_clear(mantissa);
        !           126:           return 1;
        !           127:         }
        !           128:
        !           129:       errno = 0;
        !           130:       e = strtol(str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */
        !           131:       if (*endptr != '\0')
        !           132:         {
        !           133:           mpz_clear(mantissa);
        !           134:           return 1;
        !           135:         }
        !           136:       if (errno)
        !           137:         {
        !           138:           mpz_clear(mantissa);
        !           139:           return -1;
        !           140:         }
        !           141:
        !           142:       if (e < 0 && (unsigned long) e - k < (unsigned long) LONG_MIN)
        !           143:         {
        !           144:           mpz_clear(mantissa);
        !           145:           return -1;
        !           146:         }
        !           147:       e -= k;
        !           148:     }
        !           149:   else /* unexpected character */
        !           150:     {
        !           151:       mpz_clear(mantissa);
        !           152:       return 1;
        !           153:     }
        !           154:
        !           155:   /* the number is mantissa*base^expn */
        !           156:
        !           157:   q = MPFR_PREC(x) & ~(mp_prec_t) (BITS_PER_MP_LIMB - 1);
        !           158:   mpfr_init(y);
        !           159:   mpfr_init(z);
        !           160:
        !           161:   do
        !           162:     {
        !           163:       q += BITS_PER_MP_LIMB;
        !           164:       mpfr_set_prec(y, q);
        !           165:       mpfr_set_z(y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */
        !           166:
        !           167:       mpfr_set_prec(z, q);
        !           168:       if (e > 0)
        !           169:         {
        !           170:           inex = mpfr_ui_pow_ui(z, base, e, GMP_RNDN);
        !           171:           mpfr_mul(y, y, z, GMP_RNDN);
        !           172:         }
        !           173:       else if (e < 0)
        !           174:         {
        !           175:           inex = mpfr_ui_pow_ui(z, base, -e, GMP_RNDN);
        !           176:           mpfr_div(y, y, z, GMP_RNDN);
        !           177:         }
        !           178:       else
        !           179:         inex = 1;
        !           180:       if (negative)
        !           181:         mpfr_neg(y, y, GMP_RNDN);
        !           182:     }
        !           183:   while (mpfr_can_round(y, q-inex, GMP_RNDN, rnd_mode, MPFR_PREC(x))==0
        !           184:          && q<=2*MPFR_PREC(x));
        !           185:
        !           186:   mpfr_set(x, y, rnd_mode);
        !           187:
        !           188:   mpz_clear(mantissa);
        !           189:   mpfr_clear(y);
        !           190:   mpfr_clear(z);
        !           191:   return 0;
        !           192: }
        !           193:
        !           194: int
        !           195: mpfr_init_set_str (mpfr_ptr x, char *str, int base, mp_rnd_t rnd_mode)
        !           196: {
        !           197:   mpfr_init (x);
        !           198:   return mpfr_set_str (x, str, base, rnd_mode);
        !           199: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>