summaryrefslogtreecommitdiff
path: root/mpz/get_str.c
diff options
context:
space:
mode:
authorKevin Ryde <user42@zip.com.au>2002-01-07 23:15:50 +0100
committerKevin Ryde <user42@zip.com.au>2002-01-07 23:15:50 +0100
commitc0d8acc51f2bc8389ccf4cfbd7b60ab649f9ed89 (patch)
treec8ff3388c0888479e0cb3ce04922005d1b8f212b /mpz/get_str.c
parente5f1f22cbaba9a219402309da5e64a766c694017 (diff)
downloadgmp-c0d8acc51f2bc8389ccf4cfbd7b60ab649f9ed89.tar.gz
* mpz/get_str.c: Determine realloc size arithmetically.
* mpz/get_str.c: Don't copy mpn_get_str input for power of 2 bases. * gmp-impl.h (MPN_GET_STR_SIZE): New macro. * mpn/generic/get_str.c, mpz/get_str.c, mpbsd/mout.c, mpbsd/mtox.c, tune/speed.h: Use it.
Diffstat (limited to 'mpz/get_str.c')
-rw-r--r--mpz/get_str.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/mpz/get_str.c b/mpz/get_str.c
index 752b9e7f2..3bfb23604 100644
--- a/mpz/get_str.c
+++ b/mpz/get_str.c
@@ -56,8 +56,8 @@ mpz_get_str (char *res_str, int base, mpz_srcptr x)
/* We allways allocate space for the string. If the caller passed a
NULL pointer for RES_STR, we allocate permanent space and return
a pointer to that to the caller. */
- str_size = ((size_t) (ABS (x_size) * BITS_PER_MP_LIMB
- * __mp_bases[base].chars_per_bit_exactly)) + 3;
+ MPN_GET_STR_SIZE (str_size, base, ABS (x_size));
+ str_size += 2; /* '\0' and possible '-' */
if (res_str == 0)
{
/* We didn't get a string from the user. Allocate one (and return
@@ -81,6 +81,7 @@ mpz_get_str (char *res_str, int base, mpz_srcptr x)
{
res_str[0] = '0';
res_str[1] = 0;
+ str_size = 1;
goto done;
}
if (x_size < 0)
@@ -90,9 +91,13 @@ mpz_get_str (char *res_str, int base, mpz_srcptr x)
}
/* Move the number to convert into temporary space, since mpn_get_str
- clobbers its argument + needs one extra high limb.... */
- xp = (mp_ptr) TMP_ALLOC ((x_size + 1) * BYTES_PER_MP_LIMB);
- MPN_COPY (xp, x->_mp_d, x_size);
+ clobbers its argument, except on power of 2 bases. */
+ xp = x->_mp_d;
+ if (! POW2_P (base))
+ {
+ xp = TMP_ALLOC_LIMBS (x_size);
+ MPN_COPY (xp, x->_mp_d, x_size);
+ }
str_size = mpn_get_str (str, base, xp, x_size);
@@ -115,7 +120,8 @@ mpz_get_str (char *res_str, int base, mpz_srcptr x)
required. */
if (alloc_size != 0)
{
- size_t actual_size = strlen (return_str) + 1;
+ size_t actual_size = str_size + 1 + (res_str - return_str);
+ ASSERT (actual_size == strlen (return_str) + 1);
__GMP_REALLOCATE_FUNC_MAYBE (return_str, alloc_size, actual_size);
}
return return_str;