summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Djurfeldt <djurfeldt@nada.kth.se>1999-01-21 02:13:23 +0000
committerMikael Djurfeldt <djurfeldt@nada.kth.se>1999-01-21 02:13:23 +0000
commit2a0279c9b89251c4bd13b7da45a7bdde46d99b03 (patch)
treead0b114fc2f08e23c059af9dbfca40b5eddd0211
parent6bcb5a82c3953484e365168378e8f1285697fcd7 (diff)
downloadguile-2a0279c9b89251c4bd13b7da45a7bdde46d99b03.tar.gz
* random.c: Bugfix: Retrieve and store most significant 32 bits in
different order if the machine is bigendian. (scm_init_random): Added safety check for bignum digit size.
-rw-r--r--libguile/random.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/libguile/random.c b/libguile/random.c
index c9665d6bc..d65def935 100644
--- a/libguile/random.c
+++ b/libguile/random.c
@@ -247,7 +247,11 @@ scm_i_random_bignum (SCM m, scm_rstate *state)
#endif
{
/* fix most significant 32 bits */
+#if SIZEOF_INT == 4 && defined (WORDS_BIGENDIAN)
+ w = SCM_BDIGITS (m)[nd - 1] << 16 | SCM_BDIGITS (m)[nd - 2];
+#else
w = ((LONG32 *) SCM_BDIGITS (m))[nd / 2 - 1];
+#endif
mask = (w < 0x10000
? (w < 0x100
? scm_masktab[w]
@@ -274,7 +278,12 @@ scm_i_random_bignum (SCM m, scm_rstate *state)
{
/* fix most significant 32 bits */
i /= 2;
+#if SIZEOF_INT == 4 && defined (WORDS_BIGENDIAN)
+ w = scm_the_rng.random_bits (state) & mask;
+ bits[--i] = (w & 0xffff) << 16 | w >> 16;
+#else
bits[--i] = scm_the_rng.random_bits (state) & mask;
+#endif
}
/* now fill up the rest of the bignum */
while (i)
@@ -553,5 +562,17 @@ scm_init_random ()
#include "random.x"
+ /* Check that the assumptions about bits per bignum digit are correct. */
+#if SIZEOF_INT == 4
+ m = 16;
+#else
+ m = 32;
+#endif
+ if (m != SCM_BITSPERDIG)
+ {
+ fprintf (stderr, "Internal inconsistency: Confused about bignum digit size in random.c\n");
+ exit (1);
+ }
+
scm_add_feature ("random");
}