mirror of
https://github.com/php/php-src.git
synced 2026-04-29 03:03:26 +02:00
582b724c35
The reference implementation of the "Drawing Random Floating-Point Numbers from an Interval" paper contains two mistakes that will result in erroneous values being returned under certain circumstances: - For large values of `g` the multiplication of `k * g` might overflow to infinity. - The value of `ceilint()` might exceed 2^53, possibly leading to a rounding error when promoting `k` to double within the multiplication of `k * g`. This commit updates the implementation based on Prof. Goualard suggestions after reaching out to him. It will correctly handle inputs larger than 2^-1020 in absolute values. This limitation will be documented and those inputs possibly be rejected in a follow-up commit depending on performance concerns.
42 lines
803 B
PHP
42 lines
803 B
PHP
--TEST--
|
|
Random: Randomizer: getFloat(): Extreme ranges are handled correctly
|
|
--FILE--
|
|
<?php
|
|
|
|
use Random\Engine;
|
|
use Random\Randomizer;
|
|
|
|
final class TestEngine implements Engine
|
|
{
|
|
private array $values = [
|
|
"\x64\xe8\x58\x79\x3e\xf6\x38\x00",
|
|
"\x65\xe8\x58\x79\x3e\xf6\x38\x00",
|
|
"\x00\x00\x00\x00\x00\x00\x00\x00",
|
|
];
|
|
|
|
public function generate(): string
|
|
{
|
|
return \array_shift($this->values);
|
|
}
|
|
}
|
|
|
|
$r = new Randomizer(new TestEngine());
|
|
|
|
$min = -1.6e308;
|
|
$max = 1.6e308;
|
|
printf("%.17g\n", $min);
|
|
printf("%.17g\n\n", $max);
|
|
|
|
printf("%.17g\n", $r->getFloat($min, $max));
|
|
printf("%.17g\n", $r->getFloat($min, $max));
|
|
printf("%.17g\n", $r->getFloat($min, $max));
|
|
|
|
?>
|
|
--EXPECT--
|
|
-1.6e+308
|
|
1.6e+308
|
|
|
|
-1.5999999999999998e+308
|
|
-1.6e+308
|
|
1.5999999999999998e+308
|