Re: [HACKERS] Bug: random() can return 1.0 - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: [HACKERS] Bug: random() can return 1.0
Date
Msg-id 200602011723.k11HNsd29134@candle.pha.pa.us
Whole thread Raw
List pgsql-patches
Tom Lane wrote:
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > Because random returns a double, I think it is very possible that we
> > could return 1 due to rounding,
>
> Not unless your machine has a "double" type with less than 32 bits of
> precision, which seems pretty unlikely.  It'd be sufficient to do
>
>     /* result 0.0 <= x < 1.0 */
>     result = ((double) random()) / ((double) MAX_RANDOM_VALUE + 1.0);

Here is a patch that makes this change, and cleans up other
MAX_RANDOM_VALUE uses.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: src/backend/commands/analyze.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/commands/analyze.c,v
retrieving revision 1.90
diff -c -c -r1.90 analyze.c
*** src/backend/commands/analyze.c    22 Nov 2005 18:17:08 -0000    1.90
--- src/backend/commands/analyze.c    26 Jan 2006 23:40:49 -0000
***************
*** 927,944 ****
      return numrows;
  }

! /* Select a random value R uniformly distributed in 0 < R < 1 */
  static double
  random_fract(void)
  {
!     long        z;
!
!     /* random() can produce endpoint values, try again if so */
!     do
!     {
!         z = random();
!     } while (z <= 0 || z >= MAX_RANDOM_VALUE);
!     return (double) z / (double) MAX_RANDOM_VALUE;
  }

  /*
--- 927,937 ----
      return numrows;
  }

! /* Select a random value R uniformly distributed in (0 - 1) */
  static double
  random_fract(void)
  {
!     return ((double) random() + 1) / ((double) MAX_RANDOM_VALUE + 2);
  }

  /*
Index: src/backend/storage/lmgr/s_lock.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/storage/lmgr/s_lock.c,v
retrieving revision 1.41
diff -c -c -r1.41 s_lock.c
*** src/backend/storage/lmgr/s_lock.c    22 Nov 2005 18:17:21 -0000    1.41
--- src/backend/storage/lmgr/s_lock.c    26 Jan 2006 23:40:54 -0000
***************
*** 120,126 ****

              /* increase delay by a random fraction between 1X and 2X */
              cur_delay += (int) (cur_delay *
!                   (((double) random()) / ((double) MAX_RANDOM_VALUE)) + 0.5);
              /* wrap back to minimum delay when max is exceeded */
              if (cur_delay > MAX_DELAY_MSEC)
                  cur_delay = MIN_DELAY_MSEC;
--- 120,126 ----

              /* increase delay by a random fraction between 1X and 2X */
              cur_delay += (int) (cur_delay *
!                   ((double) random() / (double) MAX_RANDOM_VALUE) + 0.5);
              /* wrap back to minimum delay when max is exceeded */
              if (cur_delay > MAX_DELAY_MSEC)
                  cur_delay = MIN_DELAY_MSEC;
Index: src/backend/utils/adt/float.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/adt/float.c,v
retrieving revision 1.119
diff -c -c -r1.119 float.c
*** src/backend/utils/adt/float.c    2 Dec 2005 02:49:11 -0000    1.119
--- src/backend/utils/adt/float.c    26 Jan 2006 23:40:57 -0000
***************
*** 1833,1840 ****
  {
      float8        result;

!     /* result 0.0-1.0 */
!     result = ((double) random()) / ((double) MAX_RANDOM_VALUE);

      PG_RETURN_FLOAT8(result);
  }
--- 1833,1840 ----
  {
      float8        result;

!     /* result [0.0 - 1.0) */
!     result = (double) random() / ((double) MAX_RANDOM_VALUE + 1);

      PG_RETURN_FLOAT8(result);
  }
Index: src/include/optimizer/geqo_random.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/optimizer/geqo_random.h,v
retrieving revision 1.16
diff -c -c -r1.16 geqo_random.h
*** src/include/optimizer/geqo_random.h    31 Dec 2004 22:03:36 -0000    1.16
--- src/include/optimizer/geqo_random.h    26 Jan 2006 23:40:58 -0000
***************
*** 28,34 ****

  /* geqo_rand returns a random float value between 0 and 1 inclusive */

! #define geqo_rand() (((double) random()) / ((double) MAX_RANDOM_VALUE))

  /* geqo_randint returns integer value between lower and upper inclusive */

--- 28,34 ----

  /* geqo_rand returns a random float value between 0 and 1 inclusive */

! #define geqo_rand() ((double) random() / (double) MAX_RANDOM_VALUE)

  /* geqo_randint returns integer value between lower and upper inclusive */


pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: test, please ignore
Next
From: Bruce Momjian
Date:
Subject: Re: New pg_dump options: exclude tables/schemas, multiple