]> sjero.net Git - wget/commitdiff
[svn] Use *rand48 where available.
authorhniksic <devnull@localhost>
Tue, 28 Jun 2005 22:22:10 +0000 (15:22 -0700)
committerhniksic <devnull@localhost>
Tue, 28 Jun 2005 22:22:10 +0000 (15:22 -0700)
ChangeLog
configure.in
src/ChangeLog
src/utils.c

index f6257845bc75ce7ea42b50ddde33181ebbae36b1..6e2669c3966676b6efa1c026ecd2e9dc320520f8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * m4/wget.m4: Use proper GPL header.
index 87d5034e0289a641b9a494b2e6fb9486c3ac9e29..af3c9e1164bc4ede8456947681e113818ab3e921 100644 (file)
@@ -204,7 +204,7 @@ dnl
 AC_FUNC_ALLOCA
 AC_FUNC_MMAP
 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)
 
 dnl We expect to have these functions on Unix-like systems configure
index 5f64abf60e3368584d8633ae80a5c936fa1ab09f..7163696d326f79fbb51d66d583556f62e70d35be 100644 (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>
 
        * main.c (secs_to_human_time): Use print_decimal when printing
index 9c8beb10f5e05062dd43896fa48ba5183ef5ff70..d785f1ba9f217baab15f183a21fbeec03b6ad50a 100644 (file)
@@ -1571,68 +1571,74 @@ determine_screen_width (void)
   return 0;
 #endif /* neither TIOCGWINSZ nor WINDOWS */
 }
+\f
+/* 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.
 
-   If MAX is greater than the value of RAND_MAX+1 on the system, the
-   returned value will be in the range [0, RAND_MAX].  This may be
-   fixed in a future release.
-
+   If the system does not support lrand48 and MAX is greater than the
+   value of RAND_MAX+1 on the system, the returned value will be in
+   the range [0, RAND_MAX].  This may be fixed in a future release.
    The random number generator is seeded automatically the first time
    it is called.
 
-   This uses rand() for portability.  It has been suggested that
-   random() offers better randomness, but this is not required for
-   Wget, so I chose to go for simplicity and use rand
-   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.  */
+   This uses lrand48 where available, rand elsewhere.  DO NOT use it
+   for cryptography.  It is only meant to be used in situations where
+   quality of the random numbers returned doesn't really matter.  */
 
 int
 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;
   int rnd;
-
-  if (!seeded)
+  if (!rnd_seeded)
     {
-      srand (time (NULL));
-      seeded = 1;
+      srand ((unsigned) time (NULL) ^ (unsigned) getpid ());
+      rnd_seeded = 1;
     }
   rnd = rand ();
 
-  /* On systems that don't define RAND_MAX, assume it to be 2**15 - 1,
-     and enforce that assumption by masking other bits.  */
-#ifndef RAND_MAX
-# define RAND_MAX 32767
-  rnd &= RAND_MAX;
-#endif
+  /* Like rand() % max, but uses the high-order bits for better
+     randomness on architectures where rand() is implemented using a
+     simple congruential generator.  */
 
-  /* This is equivalent to rand() % max, but uses the high-order bits
-     for better randomness on architecture where rand() is implemented
-     using a simple congruential generator.  */
+  bounded = (double) max * rnd / (RAND_MAX + 1.0);
+  return (int) bounded;
 
-  bounded = (double)max * rnd / (RAND_MAX + 1.0);
-  return (int)bounded;
+#endif /* not HAVE_DRAND48 */
 }
 
 /* Return a random uniformly distributed floating point number in the
-   [0, 1) range.  The precision of returned numbers is 9 digits.
-
-   Modify this to use drand48() where available!  */
+   [0, 1) range.  Uses drand48 where available, and a really lame
+   kludge elsewhere.  */
 
 double
 random_float (void)
 {
-  /* We can't rely on any specific value of RAND_MAX, but it must
-     always be greater than 1000.  */
-  int rnd1 = random_number (1000);
-  int rnd2 = random_number (1000);
-  int rnd3 = random_number (1000);
-  return rnd1 / 1000.0 + rnd2 / 1000000.0 + rnd3 / 1000000000.0;
+#ifdef HAVE_DRAND48
+  if (!rnd_seeded)
+    {
+      srand48 ((long) time (NULL) ^ (long) getpid ());
+      rnd_seeded = 1;
+    }
+  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 */
 }
 \f
 /* Implementation of run_with_timeout, a generic timeout-forcing