3v4l.org

run code in 300+ PHP versions simultaneously
<?php ini_set('serialize_precision', 13); $encoder = new FloatEncoder(); var_dump($encoder->encode(1.1234567890123456, 1, [ 'float.integers' => false, 'float.precision' => false, ], function () { })); class FloatEncoder { /** The maximum value that can be accurately represented by a float */ const FLOAT_MAX = 9007199254740992.0; /** @var array Default values for options in the encoder */ private static $defaultOptions = [ 'float.integers' => false, 'float.precision' => 17, ]; public function getDefaultOptions() { return self::$defaultOptions; } public function supports($value) { return is_float($value); } public function encode($value, $depth, array $options, callable $encode) { if (is_nan($value)) { return 'NAN'; } elseif (is_infinite($value)) { return $value < 0 ? '-INF' : 'INF'; } return $this->encodeNumber($value, $options); } /** * Encodes the number as a PHP number representation. * @param float $float The number to encode * @param array $options The float encoding options * @return string The PHP code representation for the number */ private function encodeNumber($float, array $options) { if ($this->isInteger($float, $options['float.integers'])) { return number_format($float, 0, '.', ''); } elseif ($float === 0.0) { return '0.0'; } $precision = $options['float.precision']; if ($precision === false) { $precision = ini_get('serialize_precision'); } return $this->encodeFloat($float, $precision); } /** * Tells if the number can be encoded as an integer. * @param float $float The number to test * @param bool|string $allowIntegers Whether integers should be allowed * @return bool True if the number can be encoded as an integer, false if not */ private function isInteger($float, $allowIntegers) { if (!$allowIntegers || round($float) !== $float) { return false; } elseif (abs($float) < self::FLOAT_MAX) { return true; } return $allowIntegers === 'all'; } /** * Encodes the number using a floating point representation. * @param float $float The number to encode * @param int $precision The maximum precision of encoded floats * @return string The PHP code representation for the number */ private function encodeFloat($float, $precision) { $precision = max(1, (int) $precision); $log = (int) floor(log(abs($float), 10)); if (abs($float) < self::FLOAT_MAX && $log > -5 && abs($log) < $precision) { return $this->formatFloat($float, $precision - $log - 1); } // Deal with overflow that results from rounding $log += (int) (round(abs($float) / pow(10, $log), $precision - 1) / 10); $string = $this->formatFloat($float / pow(10, $log), $precision - 1); return sprintf('%sE%+d', $string, $log); } /** * Formats the number as a decimal number. * @param float $float The number to format * @param int $digits The maximum number of decimal digits * @return string The number formatted as a decimal number */ private function formatFloat($float, $digits) { $digits = max((int) $digits, 1); $string = rtrim(number_format($float, $digits, '.', ''), '0'); return substr($string, -1) === '.' ? $string . '0' : $string; } }
Output for 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.40, 7.0.0 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.33, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.28, 8.2.0 - 8.2.18, 8.3.0 - 8.3.4, 8.3.6
string(14) "1.123456789012"
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 string(14) "1.123456789012"

preferences:
272.88 ms | 402 KiB | 376 Q