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]];
}