summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Djurfeldt <djurfeldt@nada.kth.se>1999-01-10 14:18:33 +0000
committerMikael Djurfeldt <djurfeldt@nada.kth.se>1999-01-10 14:18:33 +0000
commita7e7ea3e019038f81f45df752da254e39b4ef82c (patch)
tree80a9b90b3b235dba716378a2875323dcb376a934
parent3e8370c3e832305431c2daf1970ac0f5f476daef (diff)
downloadguile-a7e7ea3e019038f81f45df752da254e39b4ef82c.tar.gz
Fix
-rw-r--r--libguile/random.c68
1 files changed, 34 insertions, 34 deletions
diff --git a/libguile/random.c b/libguile/random.c
index 83496aa76..f77e6932e 100644
--- a/libguile/random.c
+++ b/libguile/random.c
@@ -251,33 +251,23 @@ SCM
scm_i_random_bignum (SCM m, scm_rstate *state)
{
SCM b;
- int i;
- LONG32 *bits, w, r;
- i = SCM_NUMDIGS (m);
- b = scm_mkbig (i, 0);
- bits = (LONG32 *) SCM_BDIGITS (b);
- /* treat most significant digit specially */
+ int i, nd;
+ LONG32 *bits, mask, w;
+ nd = SCM_NUMDIGS (m);
+ /* calculate mask for most significant digit */
#if SIZEOF_INT == 4
/* 16 bit digits */
- if (i & 1)
+ if (nd & 1)
{
/* 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;
- while ((r = scm_the_rng.random_bits (state) & mask) > s);
-
- ((SCM_BIGDIG *) bits)[i] = r;
- i /= 2;
- if (r < s)
- goto rest;
}
else
#endif
{
/* fix most significant 32 bits */
- LONG32 mask;
- i /= 2;
- w = ((LONG32 *) SCM_BDIGITS (m))[--i];
+ w = ((LONG32 *) SCM_BDIGITS (m))[nd / 2 - 1];
mask = (w < 0x10000
? (w < 0x100
? scm_masktab[w]
@@ -285,25 +275,35 @@ scm_i_random_bignum (SCM m, scm_rstate *state)
: (w < 0x1000000
? scm_masktab[w >> 16] << 16 | 0xFFFF
: 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 */
- while (i)
+ b = scm_mkbig (nd, 0);
+ bits = (LONG32 *) SCM_BDIGITS (b);
+ do
{
- w = ((LONG32 *) SCM_BDIGITS (m))[--i];
- while ((r = scm_the_rng.random_bits (state)) > w);
- bits[i] = r;
- if (r < w)
- goto rest;
- }
- /* now fill up the rest of the bignum */
- rest:
- while (i)
- bits[--i] = scm_the_rng.random_bits (state);
- return scm_normbig (b);
+ i = nd;
+ /* treat most significant digit specially */
+#if SIZEOF_INT == 4
+ /* 16 bit digits */
+ if (i & 1)
+ {
+ ((SCM_BIGDIG*) bits)[i - 1] = scm_the_rng.random_bits (state) & mask;
+ i /= 2;
+ }
+ else
+#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;
}
/*