summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-02-03 10:06:53 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2004-02-03 10:06:53 +0000
commita3bad9513b29aed9518992a4488556788a4248a6 (patch)
treee7924f8fc42d75d781487fff204b885dea2387e7
parenteddbad0b931c43cfbca69f0e1b43396ddbc3ebbb (diff)
downloadmpfr-a3bad9513b29aed9518992a4488556788a4248a6.tar.gz
fixed bug in get_str (case pow2, rnd=up or down)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2655 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--get_str.c22
-rw-r--r--mpfr.texi10
-rw-r--r--tests/tget_str.c20
3 files changed, 32 insertions, 20 deletions
diff --git a/get_str.c b/get_str.c
index 13beb3672..fd9e99ff4 100644
--- a/get_str.c
+++ b/get_str.c
@@ -480,20 +480,6 @@ mpfr_get_str (char *s, mp_exp_t *e, int b, size_t m, mpfr_srcptr x, mp_rnd_t rnd
return s0; /* strlen(s0) = neg + m */
}
- /* si x < 0, on se ram`ene au cas x > 0 */
- if (neg)
- {
- switch (rnd)
- {
- case GMP_RNDU :
- rnd = GMP_RNDD; break;
- case GMP_RNDD :
- rnd = GMP_RNDU; break;
- default:
- break;
- }
- }
-
if (s == NULL)
s = (char*) (*__gmp_allocate_func) (neg + m + 1);
s0 = s;
@@ -523,7 +509,7 @@ mpfr_get_str (char *s, mp_exp_t *e, int b, size_t m, mpfr_srcptr x, mp_rnd_t rnd
}
/* the first digit will contain only r bits */
- prec = (m - 1) * pow2 + r;
+ prec = (m - 1) * pow2 + r; /* total number of bits */
n = (prec - 1) / BITS_PER_MP_LIMB + 1;
TMP_MARK (marker);
@@ -568,7 +554,11 @@ mpfr_get_str (char *s, mp_exp_t *e, int b, size_t m, mpfr_srcptr x, mp_rnd_t rnd
TMP_FREE(marker);
return (s0);
- }
+ }
+
+ /* if x < 0, reduce to x > 0 */
+ if (neg)
+ rnd = MPFR_INVERT_RND(rnd);
g = mpfr_get_str_compute_g (b, MPFR_GET_EXP (x) - 1);
exact = 1;
diff --git a/mpfr.texi b/mpfr.texi
index d3331120d..0381458a3 100644
--- a/mpfr.texi
+++ b/mpfr.texi
@@ -821,12 +821,14 @@ behavior is undefined.
@deftypefun {char *} mpfr_get_str (char *@var{str}, mp_exp_t *@var{expptr}, int @var{base}, size_t @var{n}, mpfr_t @var{op}, mp_rnd_t @var{rnd})
Convert @var{op} to a string of digits in base @var{base}, with rounding in
-direction @var{rnd}. The base may vary
-from 2 to 36.
+direction @var{rnd}. The base may vary from 2 to 36.
The generated string is a fraction, with an implicit radix point immediately
-to the left of the first digit. For example, the number 3.1416 would be
-returned as "31416" in the string and 1 written at @var{expptr}.
+to the left of the first digit. For example, the number -3.1416 would be
+returned as "-31416" in the string and 1 written at @var{expptr}.
+If @var{rnd} is to nearest, and @var{op} is exactly in the middle of two
+possible outputs, the one with an even last digit is chosen
+(for an odd base, this may not correspond to an even mantissa).
If @var{n} is zero, the number of digits of the mantissa is determined
automatically from the precision of @var{op} and the value of @var{base}.
diff --git a/tests/tget_str.c b/tests/tget_str.c
index faab62088..8fbbdf0f1 100644
--- a/tests/tget_str.c
+++ b/tests/tget_str.c
@@ -185,6 +185,26 @@ check_small (void)
}
(*__gmp_free_func) (s, strlen (s) + 1);
+ mpfr_set_prec (x, 145);
+ mpfr_set_str_binary (x, "-0.1000110011000001011000010101101010110110101100101110100011111100011110011001001001010000100001000011000011000000010111011001000111101001110100110e6");
+ s = mpfr_get_str (NULL, &e, 4, 53, x, GMP_RNDU);
+ if (strcmp (s, "-20303001120111222312230232203330132121021100201003003") || (e != 3))
+ {
+ printf ("Error in mpfr_get_str (5): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
+ mpfr_set_prec (x, 45);
+ mpfr_set_str_binary (x, "-0.00100111010110010001011001110111010001010010010");
+ s = mpfr_get_str (NULL, &e, 32, 9, x, GMP_RNDN);
+ if (strcmp (s, "-4tchctq54") || (e != 0))
+ {
+ printf ("Error in mpfr_get_str (6): s=%s e=%d\n", s, (int) e);
+ exit (1);
+ }
+ (*__gmp_free_func) (s, strlen (s) + 1);
+
mpfr_clear (x);
}