37static double gamma_low(
double x)
39 return x - nextafter(x, -DBL_MAX);
42static double gamma_high(
double x)
44 return nextafter(x, DBL_MAX) - x;
47static double gamma_max(
double x,
double y)
49 return (fabs(x) > fabs(y)) ? gamma_high(x) : gamma_low(y);
52static void splitint64(uint64_t
v,
double *vhi,
double *vlo)
58static uint64_t ceilint(
double a,
double b,
double g)
60 double s = b / g -
a / g;
63 if (fabs(
a) <= fabs(b)) {
64 e = -
a / g - (
s - b / g);
66 e = b / g - (
s +
a / g);
71 return (
s != si) ? (uint64_t)si : (uint64_t)si + (e > 0);
76 double g = gamma_max(
min,
max);
77 uint64_t hi = ceilint(
min,
max, g);
85 if (fabs(
min) <= fabs(
max)) {
90 splitint64(k, &k_hi, &k_lo);
92 return 0x1p+2 * (
max * 0x1p-2 - k_hi * g) - k_lo * g;
96 splitint64(k - 1, &k_hi, &k_lo);
98 return 0x1p+2 * (
min * 0x1p-2 + k_hi * g) + k_lo * g;
104 double g = gamma_max(
min,
max);
105 uint64_t hi = ceilint(
min,
max, g);
113 if (fabs(
min) <= fabs(
max)) {
118 splitint64(k, &k_hi, &k_lo);
120 return 0x1p+2 * (
max * 0x1p-2 - k_hi * g) - k_lo * g;
127 splitint64(k, &k_hi, &k_lo);
129 return 0x1p+2 * (
min * 0x1p-2 + k_hi * g) + k_lo * g;
136 double g = gamma_max(
min,
max);
137 uint64_t hi = ceilint(
min,
max, g);
145 if (fabs(
min) <= fabs(
max)) {
147 splitint64(k, &k_hi, &k_lo);
149 return 0x1p+2 * (
max * 0x1p-2 - k_hi * g) - k_lo * g;
155 splitint64(k + 1, &k_hi, &k_lo);
157 return 0x1p+2 * (
min * 0x1p-2 + k_hi * g) + k_lo * g;
164 double g = gamma_max(
min,
max);
165 uint64_t hi = ceilint(
min,
max, g);
173 if (fabs(
min) <= fabs(
max)) {
175 splitint64(k, &k_hi, &k_lo);
177 return 0x1p+2 * (
max * 0x1p-2 - k_hi * g) - k_lo * g;
180 splitint64(k, &k_hi, &k_lo);
182 return 0x1p+2 * (
min * 0x1p-2 + k_hi * g) + k_lo * g;
PHPAPI double php_random_gammasection_closed_closed(php_random_algo_with_state engine, double min, double max)
PHPAPI double php_random_gammasection_open_closed(php_random_algo_with_state engine, double min, double max)
PHPAPI double php_random_gammasection_open_open(php_random_algo_with_state engine, double min, double max)
PHPAPI double php_random_gammasection_closed_open(php_random_algo_with_state engine, double min, double max)
struct _php_random_algo_with_state php_random_algo_with_state
PHPAPI uint64_t php_random_range64(php_random_algo_with_state engine, uint64_t umax)
#define UNEXPECTED(condition)