diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2002-04-25 09:04:20 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2002-04-25 09:04:20 +0000 |
commit | d445069d8e74762b139029ba3d59b4bf8fd59c8d (patch) | |
tree | 5f39223063223607af92ba4e66f26e49aa9bea21 /set_str.c | |
parent | 6b8f21081855bac10286fb590f4ea09f10f18594 (diff) | |
download | mpfr-d445069d8e74762b139029ba3d59b4bf8fd59c8d.tar.gz |
mpfr_set_str doesn't require any more a final '\0'
and return the number of characters read
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1917 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'set_str.c')
-rw-r--r-- | set_str.c | 94 |
1 files changed, 52 insertions, 42 deletions
@@ -47,23 +47,28 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) long e; mp_prec_t q; mpfr_t y, z; + const char *str0 = str; if (base < 2 || base > 36) - return 1; + return -1; - if (strcasecmp(str, "NaN") == 0) + /* be careful that 'nan' is a valid number in base >= 24, + since n=23, a=10, n=23 */ + if (((base < 24) ? strncasecmp : strncmp) (str, "NaN", 3) == 0) { MPFR_SET_NAN(x); /* MPFR_RET_NAN not used as the return value isn't a ternary value */ __mpfr_flags |= MPFR_FLAGS_NAN; - return 0; + return 3; } negative = *str == '-'; if (negative || *str == '+') str++; - if (strcasecmp(str, "Inf") == 0) + /* be careful that 'inf' is a valid number in base >= 24, + since i=18, n=23, f=15 */ + if (((base < 24) ? strncasecmp : strncmp) (str, "Inf", 3) == 0) { MPFR_CLEAR_NAN(x); MPFR_SET_INF(x); @@ -71,11 +76,11 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) MPFR_SET_NEG(x); else MPFR_SET_POS(x); - return 0; + return 3 + (str - str0); } - mpz_init(mantissa); - mpz_set_ui(mantissa, 0); + mpz_init (mantissa); + mpz_set_ui (mantissa, 0); while (*str == '0') str++; /* skip initial zeros */ @@ -87,8 +92,8 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) (islower(c) && c < 'a'-10 + base)) { str++; - mpz_mul_ui(mantissa, mantissa, base); - mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10)); + mpz_mul_ui (mantissa, mantissa, base); + mpz_add_ui (mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a' - 10)); } /* k is the number of non-zero digits before the decimal point */ @@ -102,37 +107,36 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) { if (k == LONG_MAX) { - mpz_clear(mantissa); + mpz_clear (mantissa); return -1; } k++; str++; - mpz_mul_ui(mantissa, mantissa, base); - mpz_add_ui(mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a'-10)); + mpz_mul_ui (mantissa, mantissa, base); + mpz_add_ui (mantissa, mantissa, isdigit(c) ? c - '0' : c - ('a' - 10)); } } - if (*str == '\0') /* no exponent */ - { - e = -k; - } - else if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@') + if ((base <= 10 && (*str == 'e' || *str == 'E')) || *str == '@') { char *endptr; if (*++str == '\0') /* exponent character but no exponent */ { - mpz_clear(mantissa); - return 1; + mpz_clear (mantissa); + return -1; } errno = 0; - e = strtol(str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */ + e = strtol (str, &endptr, 10); /* signed exponent after 'e', 'E' or '@' */ +#ifdef REQUIRE_END_OF_STRING if (*endptr != '\0') { - mpz_clear(mantissa); - return 1; + mpz_clear (mantissa); + return -1; } +#endif + str = endptr; if (errno) { mpz_clear(mantissa); @@ -146,49 +150,55 @@ mpfr_set_str (mpfr_ptr x, __gmp_const char *str, int base, mp_rnd_t rnd_mode) } e -= k; } - else /* unexpected character */ + else /* no exponent */ { - mpz_clear(mantissa); - return 1; +#ifdef REQUIRE_END_OF_STRING + if (*str != '\0') + { + mpz_clear (mantissa); + return -1; + } +#endif + e = -k; } /* the number is mantissa*base^expn */ q = MPFR_PREC(x) & ~(mp_prec_t) (BITS_PER_MP_LIMB - 1); - mpfr_init(y); - mpfr_init(z); + mpfr_init (y); + mpfr_init (z); do { q += BITS_PER_MP_LIMB; - mpfr_set_prec(y, q); - mpfr_set_z(y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */ + mpfr_set_prec (y, q); + mpfr_set_z (y, mantissa, GMP_RNDN); /* error <= 1/2*ulp(y) */ - mpfr_set_prec(z, q); + mpfr_set_prec (z, q); if (e > 0) { - inex = mpfr_ui_pow_ui(z, base, e, GMP_RNDN); - mpfr_mul(y, y, z, GMP_RNDN); + inex = mpfr_ui_pow_ui (z, base, e, GMP_RNDN); + mpfr_mul (y, y, z, GMP_RNDN); } else if (e < 0) { - inex = mpfr_ui_pow_ui(z, base, -e, GMP_RNDN); - mpfr_div(y, y, z, GMP_RNDN); + inex = mpfr_ui_pow_ui (z, base, -e, GMP_RNDN); + mpfr_div (y, y, z, GMP_RNDN); } else inex = 1; if (negative) - mpfr_neg(y, y, GMP_RNDN); + mpfr_neg (y, y, GMP_RNDN); } - while (mpfr_can_round(y, q-inex, GMP_RNDN, rnd_mode, MPFR_PREC(x))==0 - && q<=2*MPFR_PREC(x)); + while (mpfr_can_round (y, q-inex, GMP_RNDN, rnd_mode, MPFR_PREC(x)) == 0 + && q <= 2*MPFR_PREC(x)); - mpfr_set(x, y, rnd_mode); + mpfr_set (x, y, rnd_mode); - mpz_clear(mantissa); - mpfr_clear(y); - mpfr_clear(z); - return 0; + mpz_clear (mantissa); + mpfr_clear (y); + mpfr_clear (z); + return str - str0; } int |