summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-09-15 08:59:28 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2020-09-15 08:59:28 +0000
commitca334cbd97562db39c4942dd96591c0edab4766a (patch)
treea8c225bf770e8efb7057330b4d9d97193941523e
parent2a817d2fad35e6abf3bdf3c5746489d5bca8644e (diff)
downloadmpfr-ca334cbd97562db39c4942dd96591c0edab4766a.tar.gz
With mini-gmp, use the standard rand() and srand() functions instead of
the POSIX (thus less portable) lrand48() and srand48(). (merged changesets r14114-14116 from the trunk) git-svn-id: https://scm.gforge.inria.fr/anonscm/svn/mpfr/branches/4.1@14118 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--configure.ac6
-rw-r--r--doc/mini-gmp7
-rw-r--r--src/mpfr-mini-gmp.c42
3 files changed, 25 insertions, 30 deletions
diff --git a/configure.ac b/configure.ac
index 8723fce91..a0e81550f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -807,12 +807,6 @@ AC_COMPUTE_INT(mini_gmp_numb_bits, [(GMP_NUMB_BITS)],
CPPFLAGS="$saved_CPPFLAGS"
AC_MSG_RESULT([$mini_gmp_numb_bits bits ($how)])
-dnl We need to check the availability of lrand48 (used by random_limb)
-dnl and srand48 (used by gmp_randseed_ui), in particular because these
-dnl functions are not part of the ISO C standard.
-AC_CHECK_FUNC(lrand48,,AC_MSG_FAILURE([MPFR + mini-gmp requires lrand48]))
-AC_CHECK_FUNC(srand48,,AC_MSG_FAILURE([MPFR + mini-gmp requires srand48]))
-
fi
dnl End of setup related to GMP / mini-gmp
diff --git a/doc/mini-gmp b/doc/mini-gmp
index 1d8d76a08..7e66f23a5 100644
--- a/doc/mini-gmp
+++ b/doc/mini-gmp
@@ -27,10 +27,9 @@ with
before including mpfr.h (or you may want to modify mini-gmp.h).
Remark: The random functions provided by MPFR configured with mini-gmp
-use the POSIX lrand48() and srand48() functions (the platform needs to
-provide them), thus one should avoid mini-gmp if one needs some really
-serious random functions. Another consequence is that these functions
-are not thread-safe.
+use the standard rand() function, thus one should avoid mini-gmp if one
+needs some really serious random functions. Another consequence is that
+these functions may not be thread-safe.
This was tested with MPFR svn r13974 and GMP 6.2.0 on x86_64 GNU/Linux:
============================================================================
diff --git a/src/mpfr-mini-gmp.c b/src/mpfr-mini-gmp.c
index abdcb9aa2..8e0533271 100644
--- a/src/mpfr-mini-gmp.c
+++ b/src/mpfr-mini-gmp.c
@@ -40,9 +40,9 @@ 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);
+ /* Note: We possibly ignore the high-order bits of seed. One should take
+ that into account when setting GMP_CHECK_RANDOMIZE for the tests. */
+ srand ((unsigned int) seed);
}
#endif
@@ -60,26 +60,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