Skip to content

Commit be6f4ad

Browse files
committed
Add Randomizer::nextFloat()
1 parent 50e3201 commit be6f4ad

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

ext/random/random.stub.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ public function __construct(?Engine $engine = null) {}
133133

134134
public function nextInt(): int {}
135135

136+
public function nextFloat(): float {}
137+
136138
public function getInt(int $min, int $max): int {}
137139

138140
public function getBytes(int $length): string {}

ext/random/random_arginfo.h

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/random/randomizer.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,41 @@ PHP_METHOD(Random_Randomizer, nextInt)
109109
}
110110
/* }}} */
111111

112+
/* {{{ Generate a float in [0, 1) */
113+
PHP_METHOD(Random_Randomizer, nextFloat)
114+
{
115+
php_random_randomizer *randomizer = Z_RANDOM_RANDOMIZER_P(ZEND_THIS);
116+
uint64_t result;
117+
size_t total_size;
118+
119+
ZEND_PARSE_PARAMETERS_NONE();
120+
121+
result = 0;
122+
total_size = 0;
123+
do {
124+
uint64_t r = randomizer->algo->generate(randomizer->status);
125+
result = result | (r << (total_size * 8));
126+
total_size += randomizer->status->last_generated_size;
127+
if (EG(exception)) {
128+
RETURN_THROWS();
129+
}
130+
} while (total_size < sizeof(uint64_t));
131+
132+
/* A double has 53 bits of precision, thus we must not
133+
* use the full 64 bits of the uint64_t, because we would
134+
* introduce a bias / rounding error.
135+
*/
136+
const double step_size = 1.0 / (1ULL << 53);
137+
138+
/* Use the upper 53 bits, because some engine's lower bits
139+
* are of lower quality.
140+
*/
141+
result = (result >> 11);
142+
143+
RETURN_DOUBLE(step_size * result);
144+
}
145+
/* }}} */
146+
112147
/* {{{ Generate random number in range */
113148
PHP_METHOD(Random_Randomizer, getInt)
114149
{

0 commit comments

Comments
 (0)