From 114d1f074e30483b0fddd9a4cc45572b8c070797 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Sat, 18 Oct 2025 22:31:25 +0900 Subject: first commit --- src/NextAfter.php | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 src/NextAfter.php (limited to 'src') diff --git a/src/NextAfter.php b/src/NextAfter.php new file mode 100644 index 0000000..e2b7706 --- /dev/null +++ b/src/NextAfter.php @@ -0,0 +1,128 @@ + 0) { + return INF; + } + if ($x === 0.0) { + return PHP_FLOAT_MIN; + } + $u = self::floatToInt($x); + return $x > 0.0 ? self::intToFloat($u + 1) : + self::intToFloat($u - 1); + + } + + /** + * @phpstan-pure + */ + public static function nextDown(float $x): float + { + if (is_nan($x)) { + return NAN; + } + if (is_infinite($x) && $x < 0) { + return -INF; + } + if ($x === 0.0) { + return -PHP_FLOAT_MIN; + } + $u = self::floatToInt($x); + return $x > 0.0 ? self::intToFloat($u - 1) : + self::intToFloat($u + 1); + + } + + /** + * @phpstan-pure + */ + private static function intToFloat(int $x): float + { + return self::unpackFloat64(self::packInt64($x)); + } + + /** + * @phpstan-pure + */ + private static function floatToInt(float $x): int + { + return self::unpackInt64(self::packFloat64($x)); + } + + /** + * @phpstan-pure + */ + private static function unpackFloat64(string $s): float + { + assert(PHP_FLOAT_DIG === 15); // @phpstan-ignore-line + return unpack('d', $s)[1]; // @phpstan-ignore-line + } + + /** + * @phpstan-pure + */ + private static function packInt64(int $x): string + { + assert(PHP_INT_SIZE === 8); // @phpstan-ignore-line + return pack('q', $x); + } + + /** + * @phpstan-pure + */ + private static function packFloat64(float $x): string + { + assert(PHP_FLOAT_DIG === 15); // @phpstan-ignore-line + return pack('d', $x); + } + + /** + * @phpstan-pure + */ + private static function unpackInt64(string $s): int + { + assert(PHP_INT_SIZE === 8); // @phpstan-ignore-line + return unpack('q', $s)[1]; // @phpstan-ignore-line + } +} -- cgit v1.2.3-70-g09d2