Skip to content

Commit b662f1d

Browse files
committed
Preserve all digits when casting a float to string and NaN, INF, and -INF are case insensitive.
1 parent 0911f63 commit b662f1d

File tree

4 files changed

+67
-15
lines changed

4 files changed

+67
-15
lines changed

src/Cast.php

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public static function isManFloatInclusive(mixed $value): bool
9898
FILTER_SANITIZE_NUMBER_FLOAT,
9999
FILTER_FLAG_ALLOW_FRACTION | FILTER_FLAG_ALLOW_SCIENTIFIC);
100100

101-
return ($filtered===$value || in_array($value, ['NAN', 'INF', '-INF'], true));
101+
return ($filtered===$value || in_array(strtoupper($value), ['NAN', 'INF', '-INF'], true));
102102

103103
default:
104104
return false;
@@ -312,19 +312,24 @@ public static function toManFloatInclusive(mixed $value, ?float $default = null)
312312
throw new InvalidCastException('Value can not be converted to float');
313313
}
314314

315-
if ($value==='NAN')
315+
if (is_string($value))
316316
{
317-
return NAN;
318-
}
317+
$upper = strtoupper($value);
319318

320-
if ($value==='INF')
321-
{
322-
return INF;
323-
}
319+
if ($upper==='NAN')
320+
{
321+
return NAN;
322+
}
324323

325-
if ($value==='-INF')
326-
{
327-
return -INF;
324+
if ($upper==='INF')
325+
{
326+
return INF;
327+
}
328+
329+
if ($upper==='-INF')
330+
{
331+
return -INF;
332+
}
328333
}
329334

330335
return (float)$value;
@@ -386,6 +391,28 @@ public static function toManString(mixed $value, ?string $default = null): strin
386391
return '0';
387392
}
388393

394+
if (is_float($value))
395+
{
396+
if (is_nan($value))
397+
{
398+
return 'NaN';
399+
}
400+
401+
if ($value===INF)
402+
{
403+
return 'INF';
404+
}
405+
406+
if ($value===-INF)
407+
{
408+
return '-INF';
409+
}
410+
411+
$string = sprintf('%.'.PHP_FLOAT_DIG.'E', $value);
412+
413+
return preg_replace('/(\.0+E)|(0+E)/', 'E', $string);
414+
}
415+
389416
return (string)$value;
390417
}
391418

test/CastFloatInclusiveTest.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,13 @@ public function validManFloatCases(): array
224224
'expected' => INF],
225225
['value' => '-INF',
226226
'expected' => -INF],
227-
['value' => 'NAN',
227+
['value' => 'NaN',
228+
'expected' => NAN],
229+
['value' => 'inf',
230+
'expected' => INF],
231+
['value' => '-inf',
232+
'expected' => -INF],
233+
['value' => 'nan',
228234
'expected' => NAN]];
229235
}
230236

test/CastFloatTest.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ public function invalidOptFiniteFloatCases(): array
4949
[NAN],
5050
['INF'],
5151
['-INF'],
52-
['NAN']];
52+
['NaN'],
53+
['inf'],
54+
['-inf'],
55+
['nan']];
5356
}
5457

5558
//--------------------------------------------------------------------------------------------------------------------

test/CastStringTest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,22 @@ public function testManStringWithValidValues(mixed $value, string $expected): vo
9292
self::assertSame($expected, $casted);
9393
}
9494

95+
//--------------------------------------------------------------------------------------------------------------------
96+
/**
97+
* Test the number of digits of a float cast tot a string.
98+
*/
99+
public function testOptStringDigits(): void
100+
{
101+
$pi = Cast::toOptString(M_PI);
102+
self::assertEquals(PHP_FLOAT_DIG + 5, strlen($pi));
103+
104+
$value = Cast::toOptString(100.0);
105+
self::assertEquals('1E+2', $value);
106+
107+
$value = Cast::toOptString(0.01);
108+
self::assertEquals('1E-2', $value);
109+
}
110+
95111
//--------------------------------------------------------------------------------------------------------------------
96112
/**
97113
* Test with default value.
@@ -174,13 +190,13 @@ public function validManStringCases(): array
174190

175191
// Float test cases.
176192
$cases[] = ['value' => 123.0,
177-
'expected' => '123'];
193+
'expected' => '1.23E+2'];
178194
$cases[] = ['value' => INF,
179195
'expected' => 'INF'];
180196
$cases[] = ['value' => -INF,
181197
'expected' => '-INF'];
182198
$cases[] = ['value' => NAN,
183-
'expected' => 'NAN'];
199+
'expected' => 'NaN'];
184200

185201
// Boolean test cases.
186202
$cases[] = ['value' => false,

0 commit comments

Comments
 (0)