diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2003-02-27 10:20:34 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2003-02-27 10:20:34 +0000 |
commit | 27af749912c743bc9c81acaf81d2661397b69e3f (patch) | |
tree | df34a8a147e10392ae710fde66f59068d0a21cdc | |
parent | 54b77a5f5b256d816e0f0e8d3a2d5c09cd822e3a (diff) | |
download | mpfr-27af749912c743bc9c81acaf81d2661397b69e3f.tar.gz |
mpfr_set_str now accepts a binary exponent for base 16
(as defined by the ISO C99 standard).
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2252 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | mpfr.texi | 10 | ||||
-rw-r--r-- | set_str.c | 18 | ||||
-rw-r--r-- | tests/tset_str.c | 16 |
3 files changed, 36 insertions, 8 deletions
@@ -1349,10 +1349,12 @@ Return the number of bytes written, or if an error occurred, return 0. Input a string in base @var{base} from stdio stream @var{stream}, rounded in direction @var{rnd}, and put the read float in @var{rop}. The string is of the form @samp{M@@N} or, if the -base is 10 or less, alternatively @samp{MeN} or @samp{MEN}. -@samp{M} is the mantissa and -@samp{N} is the exponent. The mantissa is always in the specified base. The -exponent is read in decimal. +base is 10 or less, alternatively @samp{MeN} or @samp{MEN}, or, if the base +is 16, alternatively @samp{MpB} or @samp{MPB}. +@samp{M} is the mantissa in the specified base, @samp{N} is the exponent +written in decimal for the specified base, and in base 16, @samp{B} is the +binary exponent written in decimal (it indicates the power of 2 by which +the mantissa is to be scaled). The argument @var{base} may be in the range 2 to 36. Unlike the corresponding @code{mpz} function, the base will not be determined @@ -79,6 +79,7 @@ mpfr_set_str (mpfr_t x, const char *str, int base, mp_rnd_t rnd) mp_exp_t pr; /* needed precision requise for str */ mp_exp_t exp_s = 0; /* exponent in base 'base', normalized for a mantissa 0.xxx...xxx */ + mp_exp_t binexp = 0; /* binary exponent (for base 16) */ mp_exp_t prec_x; /* working precision for x */ char *str1; /* copy of str, should not be modified */ size_t size_str1; /* number of characters in str1 */ @@ -146,6 +147,17 @@ mpfr_set_str (mpfr_t x, const char *str, int base, mp_rnd_t rnd) } break; } + else if (base == 16 && (*str == 'p' || *str == 'P')) + { + char *endptr[1]; + binexp = (mp_exp_t) strtol (str + 1, endptr, 10); + if (**endptr != '\0') + { + res = -1; /* invalid input: garbage after exponent */ + goto end; + } + break; + } else if (*str == '.') { point = 1; @@ -177,7 +189,7 @@ mpfr_set_str (mpfr_t x, const char *str, int base, mp_rnd_t rnd) goto sign_and_flags; } - /* now we have str = 0.mant_s[0]...mant_s[prec_s-1]*base^exp_s */ + /* now we have str = 0.mant_s[0]...mant_s[prec_s-1]*base^exp_s*2^binexp */ /* determine the minimal precision for the computation */ prec_x = MPFR_PREC(x) + (mp_exp_t) __gmpfr_ceil_log2 ((double) MPFR_PREC(x)); @@ -239,8 +251,8 @@ mpfr_set_str (mpfr_t x, const char *str, int base, mp_rnd_t rnd) count_leading_zeros (pow2, (mp_limb_t) base); pow2 = BITS_PER_MP_LIMB - pow2 - 1; /* base = 2^pow2 */ - - exp_y = exp_y + pow2 * (exp_s - (mp_exp_t) pr); + + exp_y += pow2 * (exp_s - (mp_exp_t) pr) + binexp; result = y - n; } diff --git a/tests/tset_str.c b/tests/tset_str.c index e8a31f18e..1eb550908 100644 --- a/tests/tset_str.c +++ b/tests/tset_str.c @@ -89,7 +89,7 @@ main (int argc, char *argv[]) mpfr_set_str (y, "4.936a52bc17254@-133", 16, GMP_RNDN); if (mpfr_cmp (x, y)) { - fprintf (stderr, "Error in mpfr_set_str (1):\n"); + fprintf (stderr, "Error in mpfr_set_str (1a):\n"); mpfr_print_binary (x); putchar ('\n'); mpfr_print_binary (y); @@ -99,6 +99,20 @@ main (int argc, char *argv[]) exit (1); } + mpfr_set_str_raw (x, "0.111111101101110010111010100110000111011001010100001101E-529"); + mpfr_set_str (y, "0.fedcba98765434P-529", 16, GMP_RNDN); + if (mpfr_cmp (x, y)) + { + fprintf (stderr, "Error in mpfr_set_str (1b):\n"); + mpfr_print_binary (x); + putchar ('\n'); + mpfr_print_binary (y); + putchar ('\n'); + mpfr_clear (x); + mpfr_clear (y); + exit (1); + } + (*__gmp_free_func) (str, nc * sizeof(char)); mpfr_set_prec (x, 53); |