summaryrefslogtreecommitdiff
path: root/src/mpfr-mini-gmp.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-09-14 13:59:34 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-09-14 13:59:34 +0000
commite53ade9c96561bb0775e012591e2cae823aa8f9d (patch)
tree7c214cffe31936bca903e6cac1c51bb67ebad4c9 /src/mpfr-mini-gmp.c
parent274fcefc501bc56656b8f69a0e9bb8ec92ae8cf3 (diff)
downloadmpfr-e53ade9c96561bb0775e012591e2cae823aa8f9d.tar.gz
With mini-gmp, use the standard rand() and srand() functions instead of
the POSIX (thus less portable) lrand48() and srand48(). git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/trunk@14114 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src/mpfr-mini-gmp.c')
-rw-r--r--src/mpfr-mini-gmp.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/src/mpfr-mini-gmp.c b/src/mpfr-mini-gmp.c
index abdcb9aa2..d39cf968b 100644
--- a/src/mpfr-mini-gmp.c
+++ b/src/mpfr-mini-gmp.c
@@ -40,9 +40,15 @@ gmp_randinit_default (gmp_randstate_t state)
void
gmp_randseed_ui (gmp_randstate_t state, unsigned long int seed)
{
- /* With a portable version of the conversion from unsigned long to long
- (at least GCC and Clang optimize this expression to identity). */
- srand48 (seed > LONG_MAX ? -1 - (long) ~seed : (long) seed);
+ unsigned int s = seed;
+
+ while (seed > UINT_MAX)
+ {
+ seed /= (unsigned long int) UINT_MAX + 1;
+ s |= seed;
+ }
+
+ srand (seed);
}
#endif
@@ -60,26 +66,28 @@ gmp_randinit_set (gmp_randstate_t s1, gmp_randstate_t s2)
}
#endif
+static unsigned int
+rand15 (void)
+{
+ /* With a good PRNG, we could use "rand () % 32768", but let's choose
+ the following from <http://c-faq.com/lib/randrange.html>. Note that
+ on most platforms, the compiler should generate a shift. */
+ return rand () / (RAND_MAX / 32768 + 1);
+}
+
static mp_limb_t
random_limb (void)
{
- /* lrand48() returns a random number in [0, 2^31-1],
- but the low 15 bits do not depend on the random seed,
- thus it is safer to use the upper bits */
-#if GMP_NUMB_BITS < 32
- /* use the upper GMP_NUMB_BITS bits from lrand48 () */
- return (mp_limb_t) (lrand48 () >> (31 - GMP_NUMB_BITS));
-#elif GMP_NUMB_BITS == 32
- /* use the upper 16 bits from two lrand48 calls */
- return (lrand48 () >> 15) + ((lrand48 () >> 15) << 16);
-#elif GMP_NUMB_BITS == 64
- /* use the upper 16 bits from four lrand48 calls */
- return (lrand48 () >> 15) + ((((mp_limb_t) lrand48 ()) >> 15) << 16)
- + ((((mp_limb_t) lrand48 ()) >> 15) << 32)
- + ((((mp_limb_t) lrand48 ()) >> 15) << 48);
-#else
-#error "GMP_NUMB_BITS should be 8, 16, 32 or >= 64"
-#endif
+ mp_limb_t r = 0;
+ int i = GMP_NUMB_BITS;
+
+ while (i > 0)
+ {
+ r = (r << 15) | rand15 ();
+ i -= 15;
+ }
+
+ return r;
}
#ifdef WANT_mpz_urandomb