From a26ed4ce2002593e42d474460796c7b454e9acca Mon Sep 17 00:00:00 2001 From: Paul Water Date: Sun, 10 May 2020 13:05:36 +0200 Subject: [PATCH] Convert non finite floats 'INF', '-INF', and 'NAN' strings to floats. --- src/Cast.php | 34 +++++++++++++++++++++++++++++++--- test/CastFloatTest.php | 6 ++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/Cast.php b/src/Cast.php index 8802d62..cadec39 100644 --- a/src/Cast.php +++ b/src/Cast.php @@ -33,7 +33,7 @@ public static function isManBool($value): bool //-------------------------------------------------------------------------------------------------------------------- /** - * Returns true if and only if a value is not null and can be casted to a finite float. Otherwise returns false. + * Returns true if and only if a value is not null and can be casted to a float. Otherwise returns false. * * @param mixed $value The value. * @@ -41,7 +41,31 @@ public static function isManBool($value): bool */ public static function isManFiniteFloat($value): bool { - return (static::isManFloat($value) && is_finite((float)$value)); + switch (gettype($value)) + { + case 'boolean': + case 'integer': + return true; + + case 'double': + return is_finite($value); + + case 'string': + // Reject empty strings. + if ($value==='') return false; + + // Reject leading zeros unless they are followed by a decimal point + if (strlen($value)>1 && $value[0]==='0' && $value[1]!=='.') return false; + + $filtered = filter_var($value, + FILTER_SANITIZE_NUMBER_FLOAT, + FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_SCIENTIFIC); + + return ($filtered===$value); + + default: + return false; + } } //-------------------------------------------------------------------------------------------------------------------- @@ -72,7 +96,7 @@ public static function isManFloat($value): bool FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_SCIENTIFIC); - return ($filtered===$value); + return ($filtered===$value || in_array($value, ['NAN', 'INF', '-INF'], true)); default: return false; @@ -291,6 +315,10 @@ public static function toManFloat($value, ?float $default = null): float throw new InvalidCastException('Value can not be converted to float'); } + if ($value==='NAN') return NAN; + if ($value==='INF') return INF; + if ($value==='-INF') return -INF; + return (float)$value; } diff --git a/test/CastFloatTest.php b/test/CastFloatTest.php index e11a84f..6ea3148 100644 --- a/test/CastFloatTest.php +++ b/test/CastFloatTest.php @@ -219,6 +219,12 @@ public function validManFloatCases(): array ['value' => -INF, 'expected' => -INF], ['value' => NAN, + 'expected' => NAN], + ['value' => 'INF', + 'expected' => INF], + ['value' => '-INF', + 'expected' => -INF], + ['value' => 'NAN', 'expected' => NAN]]; }