1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 20:00:19 +02:00
This commit is contained in:
Mikael Djurfeldt 1999-01-10 14:18:33 +00:00
parent 3e8370c3e8
commit a7e7ea3e01

View file

@ -251,33 +251,23 @@ SCM
scm_i_random_bignum (SCM m, scm_rstate *state) scm_i_random_bignum (SCM m, scm_rstate *state)
{ {
SCM b; SCM b;
int i; int i, nd;
LONG32 *bits, w, r; LONG32 *bits, mask, w;
i = SCM_NUMDIGS (m); nd = SCM_NUMDIGS (m);
b = scm_mkbig (i, 0); /* calculate mask for most significant digit */
bits = (LONG32 *) SCM_BDIGITS (b);
/* treat most significant digit specially */
#if SIZEOF_INT == 4 #if SIZEOF_INT == 4
/* 16 bit digits */ /* 16 bit digits */
if (i & 1) if (nd & 1)
{ {
/* fix most significant 16 bits */ /* fix most significant 16 bits */
unsigned short mask, r, s = SCM_BDIGITS (m)[--i]; unsigned short s = SCM_BDIGITS (m)[nd - 1];
mask = s < 0x100 ? scm_masktab[s] : scm_masktab[s >> 8] << 8 | 0xFF; mask = s < 0x100 ? scm_masktab[s] : scm_masktab[s >> 8] << 8 | 0xFF;
while ((r = scm_the_rng.random_bits (state) & mask) > s);
((SCM_BIGDIG *) bits)[i] = r;
i /= 2;
if (r < s)
goto rest;
} }
else else
#endif #endif
{ {
/* fix most significant 32 bits */ /* fix most significant 32 bits */
LONG32 mask; w = ((LONG32 *) SCM_BDIGITS (m))[nd / 2 - 1];
i /= 2;
w = ((LONG32 *) SCM_BDIGITS (m))[--i];
mask = (w < 0x10000 mask = (w < 0x10000
? (w < 0x100 ? (w < 0x100
? scm_masktab[w] ? scm_masktab[w]
@ -285,25 +275,35 @@ scm_i_random_bignum (SCM m, scm_rstate *state)
: (w < 0x1000000 : (w < 0x1000000
? scm_masktab[w >> 16] << 16 | 0xFFFF ? scm_masktab[w >> 16] << 16 | 0xFFFF
: scm_masktab[w >> 24] << 24 | 0xFFFFFF)); : scm_masktab[w >> 24] << 24 | 0xFFFFFF));
while ((r = scm_the_rng.random_bits (state) & mask) > w);
bits[i] = r;
if (r < w)
goto rest;
} }
/* fill and compare */ b = scm_mkbig (nd, 0);
while (i) bits = (LONG32 *) SCM_BDIGITS (b);
do
{ {
w = ((LONG32 *) SCM_BDIGITS (m))[--i]; i = nd;
while ((r = scm_the_rng.random_bits (state)) > w); /* treat most significant digit specially */
bits[i] = r; #if SIZEOF_INT == 4
if (r < w) /* 16 bit digits */
goto rest; if (i & 1)
} {
/* now fill up the rest of the bignum */ ((SCM_BIGDIG*) bits)[i - 1] = scm_the_rng.random_bits (state) & mask;
rest: i /= 2;
while (i) }
bits[--i] = scm_the_rng.random_bits (state); else
return scm_normbig (b); #endif
{
/* fix most significant 32 bits */
i /= 2;
bits[--i] = scm_the_rng.random_bits (state) & mask;
}
/* now fill up the rest of the bignum */
while (i)
bits[--i] = scm_the_rng.random_bits (state);
b = scm_normbig (b);
if (SCM_INUMP (b))
return b;
} while (scm_bigcomp (b, m) <= 0);
return b;
} }
/* /*