[Gmp-commit] /var/hg/gmp-proj/mini-gmp: Split _set_str in two functions, for ...
mercurial at gmplib.org
mercurial at gmplib.org
Sat Dec 31 08:46:26 CET 2011
details: /var/hg/gmp-proj/mini-gmp/rev/00bd9d685574
changeset: 23:00bd9d685574
user: Niels M?ller <nisse at lysator.liu.se>
date: Sat Dec 31 08:36:51 2011 +0100
description:
Split _set_str in two functions, for powers of two and other bases.
diffstat:
mini-gmp.c | 244 ++++++++++++++++++++++++++++++------------------------------
1 files changed, 122 insertions(+), 122 deletions(-)
diffs (truncated from 341 to 300 lines):
diff -r 31a06c346680 -r 00bd9d685574 mini-gmp.c
--- a/mini-gmp.c Fri Dec 30 22:42:22 2011 +0100
+++ b/mini-gmp.c Sat Dec 31 08:36:51 2011 +0100
@@ -884,12 +884,27 @@
}
}
+static unsigned
+base_power_of_two_p (unsigned b)
+{
+ switch (b)
+ {
+ case 2: return 1;
+ case 4: return 2;
+ case 8: return 3;
+ case 16: return 4;
+ case 32: return 5;
+ case 64: return 6;
+ case 128: return 7;
+ case 256: return 8;
+ default: return 0;
+ }
+}
+
struct mpn_base_info
{
- /* When base is a power of two, bits is non-zero and the other
- fields are unused. For other bases, bits is zero and bb is the
- largest power of the base which fits in one limb. */
- unsigned bits;
+ /* bb is the largest power of the base which fits in one limb, and
+ exp is the corresponding exponent. */
unsigned exp;
mp_limb_t bb;
};
@@ -897,53 +912,16 @@
static void
mpn_get_base_info (struct mpn_base_info *info, mp_limb_t b)
{
- if ( (b & (b-1)) == 0)
- {
- /* Power of two */
- switch (b)
- {
- case 2:
- info->bits = 1;
- break;
- case 4:
- info->bits = 2;
- break;
- case 8:
- info->bits = 3;
- break;
- case 16:
- info->bits = 4;
- break;
- case 32:
- info->bits = 5;
- break;
- case 64:
- info->bits = 6;
- break;
- case 128:
- info->bits = 7;
- break;
- case 256:
- info->bits = 8;
- break;
- default:
- die ("Unsupported base.");
- }
- }
- else
- {
- mp_limb_t m;
- mp_limb_t p;
- unsigned exp;
+ mp_limb_t m;
+ mp_limb_t p;
+ unsigned exp;
- m = MP_LIMB_T_MAX / b;
- for (exp = 1, p = b; p <= m; exp++)
- p *= b;
+ m = MP_LIMB_T_MAX / b;
+ for (exp = 1, p = b; p <= m; exp++)
+ p *= b;
- info->bits = 0;
- info->exp = exp;
- info->bb = p;
- }
+ info->exp = exp;
+ info->bb = p;
}
mp_bitcnt_t
@@ -1051,97 +1029,109 @@
size_t
mpn_get_str (unsigned char *sp, int base, mp_ptr up, mp_size_t un)
{
- struct mpn_base_info info;
+ unsigned bits;
assert (un > 0);
assert (up[un-1] > 0);
- mpn_get_base_info (&info, base);
+ bits = base_power_of_two_p (base);
+ if (bits)
+ return mpn_get_str_bits (sp, bits, up, un);
+ else
+ {
+ struct mpn_base_info info;
- if (info.bits)
- /* Power of two */
- return mpn_get_str_bits (sp, info.bits, up, un);
- else
- return mpn_get_str_other (sp, base, &info, up, un);
+ mpn_get_base_info (&info, base);
+ return mpn_get_str_other (sp, base, &info, up, un);
+ }
}
static mp_size_t
-mpn_set_str_pre (mp_ptr rp, const unsigned char *sp, size_t sn,
- mp_limb_t b, const struct mpn_base_info *info)
+mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn,
+ unsigned bits)
{
mp_size_t rn;
+ size_t j;
+ unsigned shift;
- assert (sn > 0);
-
- if (info->bits)
+ for (j = sn, rn = 0, shift = 0; j-- > 0; )
{
- size_t j;
- unsigned bits;
-
- for (j = sn, rn = 0, bits = 0; j-- > 0; )
+ if (shift == 0)
{
- if (bits == 0)
+ rp[rn++] = sp[j];
+ shift += bits;
+ }
+ else
+ {
+ rp[rn-1] |= (mp_limb_t) sp[j] << shift;
+ shift += bits;
+ if (shift >= GMP_LIMB_BITS)
{
- rp[rn++] = sp[j];
- bits += info->bits;
- }
- else
- {
- rp[rn-1] |= (mp_limb_t) sp[j] << bits;
- bits += info->bits;
- if (bits >= GMP_LIMB_BITS)
- {
- bits -= GMP_LIMB_BITS;
- if (bits > 0)
- rp[rn++] = (mp_limb_t) sp[j] >> (info->bits - bits);
- }
+ shift -= GMP_LIMB_BITS;
+ if (shift > 0)
+ rp[rn++] = (mp_limb_t) sp[j] >> (bits - shift);
}
}
- rn = mpn_normalized_size (rp, rn);
}
- else
+ rn = mpn_normalized_size (rp, rn);
+ return rn;
+}
+
+static mp_size_t
+mpn_set_str_other (mp_ptr rp, const unsigned char *sp, size_t sn,
+ mp_limb_t b, const struct mpn_base_info *info)
+{
+ mp_size_t rn;
+ mp_limb_t w;
+ unsigned first;
+ unsigned k;
+ size_t j;
+
+ first = 1 + (sn - 1) % info->exp;
+
+ j = 0;
+ w = sp[j++];
+ for (k = 1; k < first; k++)
+ w = w * b + sp[j++];
+
+ rp[0] = w;
+
+ for (rn = (w > 0); j < sn;)
{
- mp_limb_t w;
- unsigned first;
- unsigned k;
- size_t j;
+ mp_limb_t cy;
- first = 1 + (sn - 1) % info->exp;
-
- j = 0;
w = sp[j++];
- for (k = 1; k < first; k++)
+ for (k = 1; k < info->exp; k++)
w = w * b + sp[j++];
- rp[0] = w;
- for (rn = (w > 0); j < sn;)
- {
- mp_limb_t cy;
+ cy = mpn_mul_1 (rp, rp, rn, info->bb);
+ cy += mpn_add_1 (rp, rp, rn, w);
+ if (cy > 0)
+ rp[rn++] = cy;
+ }
+ assert (j == sn);
- w = sp[j++];
- for (k = 1; k < info->exp; k++)
- w = w * b + sp[j++];
-
- cy = mpn_mul_1 (rp, rp, rn, info->bb);
- cy += mpn_add_1 (rp, rp, rn, w);
- if (cy > 0)
- rp[rn++] = cy;
- }
- assert (j == sn);
- }
return rn;
}
mp_size_t
mpn_set_str (mp_ptr rp, const unsigned char *sp, size_t sn, int base)
{
- struct mpn_base_info info;
+ unsigned bits;
if (sn == 0)
return 0;
- mpn_get_base_info (&info, base);
- return mpn_set_str_pre (rp, sp, sn, base, &info);
+ bits = base_power_of_two_p (base);
+ if (bits)
+ return mpn_set_str_bits (rp, sp, sn, bits);
+ else
+ {
+ struct mpn_base_info info;
+
+ mpn_get_base_info (&info, base);
+ return mpn_set_str_other (rp, sp, sn, base, &info);
+ }
}
@@ -1890,7 +1880,7 @@
char *
mpz_get_str (char *sp, int base, const mpz_t u)
{
- struct mpn_base_info info;
+ unsigned bits;
const char *digits;
mp_size_t un;
size_t i, sn;
@@ -1927,14 +1917,18 @@
if (u->_mp_size < 0)
sp[i++] = '-';
- mpn_get_base_info (&info, base);
+ bits = base_power_of_two_p (base);
- if (info.bits)
+ if (bits)
/* Not modified in this case. */
- sn = i + mpn_get_str_bits ((unsigned char *) sp + i, info.bits, u->_mp_d, un);
+ sn = i + mpn_get_str_bits ((unsigned char *) sp + i, bits, u->_mp_d, un);
else
{
- mp_ptr tp = xalloc_limbs (un);
+ struct mpn_base_info info;
+ mp_ptr tp;
+
+ mpn_get_base_info (&info, base);
+ tp = xalloc_limbs (un);
mpn_copyi (tp, u->_mp_d, un);
sn = i + mpn_get_str_other ((unsigned char *) sp + i, base, &info, tp, un);
@@ -1951,7 +1945,7 @@
int
mpz_set_str (mpz_t r, const char *sp, int base)
More information about the gmp-commit
mailing list