[svn] Use *rand48 where available.

This commit is contained in:
hniksic 2005-06-28 15:22:10 -07:00
parent e289d2ecc4
commit b8456c0fb4
4 changed files with 53 additions and 38 deletions

View File

@ -1,3 +1,7 @@
2005-06-29 Hrvoje Niksic <hniksic@xemacs.org>
* configure.in: Check for drand48.
2005-06-26 Hrvoje Niksic <hniksic@xemacs.org> 2005-06-26 Hrvoje Niksic <hniksic@xemacs.org>
* m4/wget.m4: Use proper GPL header. * m4/wget.m4: Use proper GPL header.

View File

@ -204,7 +204,7 @@ dnl
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
AC_FUNC_MMAP AC_FUNC_MMAP
AC_FUNC_FSEEKO AC_FUNC_FSEEKO
AC_CHECK_FUNCS(strptime timegm snprintf vsnprintf) AC_CHECK_FUNCS(strptime timegm snprintf vsnprintf drand48)
AC_CHECK_FUNCS(usleep ftello sigblock sigsetjmp symlink) AC_CHECK_FUNCS(usleep ftello sigblock sigsetjmp symlink)
dnl We expect to have these functions on Unix-like systems configure dnl We expect to have these functions on Unix-like systems configure

View File

@ -1,3 +1,8 @@
2005-06-29 Hrvoje Niksic <hniksic@xemacs.org>
* utils.c (random_number): Use lrand48 if available.
(random_float): Use drand48 if available.
2005-06-29 Hrvoje Niksic <hniksic@xemacs.org> 2005-06-29 Hrvoje Niksic <hniksic@xemacs.org>
* main.c (secs_to_human_time): Use print_decimal when printing * main.c (secs_to_human_time): Use print_decimal when printing

View File

@ -1571,68 +1571,74 @@ determine_screen_width (void)
return 0; return 0;
#endif /* neither TIOCGWINSZ nor WINDOWS */ #endif /* neither TIOCGWINSZ nor WINDOWS */
} }
/* Whether the rnd system (either rand or [dl]rand48) has been
seeded. */
static int rnd_seeded;
/* Return a random number between 0 and MAX-1, inclusive. /* Return a random number between 0 and MAX-1, inclusive.
If MAX is greater than the value of RAND_MAX+1 on the system, the If the system does not support lrand48 and MAX is greater than the
returned value will be in the range [0, RAND_MAX]. This may be value of RAND_MAX+1 on the system, the returned value will be in
fixed in a future release. the range [0, RAND_MAX]. This may be fixed in a future release.
The random number generator is seeded automatically the first time The random number generator is seeded automatically the first time
it is called. it is called.
This uses rand() for portability. It has been suggested that This uses lrand48 where available, rand elsewhere. DO NOT use it
random() offers better randomness, but this is not required for for cryptography. It is only meant to be used in situations where
Wget, so I chose to go for simplicity and use rand quality of the random numbers returned doesn't really matter. */
unconditionally.
DO NOT use this for cryptographic purposes. It is only meant to be
used in situations where quality of the random numbers returned
doesn't really matter. */
int int
random_number (int max) random_number (int max)
{ {
static int seeded; #ifdef HAVE_DRAND48
if (!rnd_seeded)
{
srand48 ((long) time (NULL) ^ (long) getpid ());
rnd_seeded = 1;
}
return lrand48 () % max;
#else /* not HAVE_DRAND48 */
double bounded; double bounded;
int rnd; int rnd;
if (!rnd_seeded)
if (!seeded)
{ {
srand (time (NULL)); srand ((unsigned) time (NULL) ^ (unsigned) getpid ());
seeded = 1; rnd_seeded = 1;
} }
rnd = rand (); rnd = rand ();
/* On systems that don't define RAND_MAX, assume it to be 2**15 - 1, /* Like rand() % max, but uses the high-order bits for better
and enforce that assumption by masking other bits. */ randomness on architectures where rand() is implemented using a
#ifndef RAND_MAX simple congruential generator. */
# define RAND_MAX 32767
rnd &= RAND_MAX;
#endif
/* This is equivalent to rand() % max, but uses the high-order bits bounded = (double) max * rnd / (RAND_MAX + 1.0);
for better randomness on architecture where rand() is implemented return (int) bounded;
using a simple congruential generator. */
bounded = (double)max * rnd / (RAND_MAX + 1.0); #endif /* not HAVE_DRAND48 */
return (int)bounded;
} }
/* Return a random uniformly distributed floating point number in the /* Return a random uniformly distributed floating point number in the
[0, 1) range. The precision of returned numbers is 9 digits. [0, 1) range. Uses drand48 where available, and a really lame
kludge elsewhere. */
Modify this to use drand48() where available! */
double double
random_float (void) random_float (void)
{ {
/* We can't rely on any specific value of RAND_MAX, but it must #ifdef HAVE_DRAND48
always be greater than 1000. */ if (!rnd_seeded)
int rnd1 = random_number (1000); {
int rnd2 = random_number (1000); srand48 ((long) time (NULL) ^ (long) getpid ());
int rnd3 = random_number (1000); rnd_seeded = 1;
return rnd1 / 1000.0 + rnd2 / 1000000.0 + rnd3 / 1000000000.0; }
return drand48 ();
#else /* not HAVE_DRAND48 */
return ( random_number (10000) / 10000.0
+ random_number (10000) / (10000.0 * 10000.0)
+ random_number (10000) / (10000.0 * 10000.0 * 10000.0)
+ random_number (10000) / (10000.0 * 10000.0 * 10000.0 * 10000.0));
#endif /* not HAVE_DRAND48 */
} }
/* Implementation of run_with_timeout, a generic timeout-forcing /* Implementation of run_with_timeout, a generic timeout-forcing