diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2023-01-09 12:44:00 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2023-01-09 12:44:00 -0500 |
commit | 38d81760c4d7e22b95252e3545596602c9e38806 (patch) | |
tree | c5f8802619bf418dbdcc40392bb6d47123861908 /src/backend/utils/adt/float.c | |
parent | 2673ebf49acfd83b09c777ced8f21eacd27b51ce (diff) | |
download | postgresql-38d81760c4d7e22b95252e3545596602c9e38806.tar.gz postgresql-38d81760c4d7e22b95252e3545596602c9e38806.zip |
Invent random_normal() to provide normally-distributed random numbers.
There is already a version of this in contrib/tablefunc, but it
seems sufficiently widely useful to justify having it in core.
Paul Ramsey
Discussion: https://postgr.es/m/CACowWR0DqHAvOKUCNxTrASFkWsDLqKMd6WiXvVvaWg4pV1BMnQ@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/float.c')
-rw-r--r-- | src/backend/utils/adt/float.c | 40 |
1 files changed, 35 insertions, 5 deletions
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 56e349b8889..d290b4ca67c 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -2743,13 +2743,11 @@ datanh(PG_FUNCTION_ARGS) /* - * drandom - returns a random number + * initialize_drandom_seed - initialize drandom_seed if not yet done */ -Datum -drandom(PG_FUNCTION_ARGS) +static void +initialize_drandom_seed(void) { - float8 result; - /* Initialize random seed, if not done yet in this process */ if (unlikely(!drandom_seed_set)) { @@ -2769,6 +2767,17 @@ drandom(PG_FUNCTION_ARGS) } drandom_seed_set = true; } +} + +/* + * drandom - returns a random number + */ +Datum +drandom(PG_FUNCTION_ARGS) +{ + float8 result; + + initialize_drandom_seed(); /* pg_prng_double produces desired result range [0.0 - 1.0) */ result = pg_prng_double(&drandom_seed); @@ -2776,6 +2785,27 @@ drandom(PG_FUNCTION_ARGS) PG_RETURN_FLOAT8(result); } +/* + * drandom_normal - returns a random number from a normal distribution + */ +Datum +drandom_normal(PG_FUNCTION_ARGS) +{ + float8 mean = PG_GETARG_FLOAT8(0); + float8 stddev = PG_GETARG_FLOAT8(1); + float8 result, + z; + + initialize_drandom_seed(); + + /* Get random value from standard normal(mean = 0.0, stddev = 1.0) */ + z = pg_prng_double_normal(&drandom_seed); + /* Transform the normal standard variable (z) */ + /* using the target normal distribution parameters */ + result = (stddev * z) + mean; + + PG_RETURN_FLOAT8(result); +} /* * setseed - set seed for the random number generator |