1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-27 12:41:57 +03:00

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
This commit is contained in:
Tom Lane
2023-01-09 12:44:00 -05:00
parent 2673ebf49a
commit 38d81760c4
10 changed files with 164 additions and 29 deletions

View File

@ -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