Skip to content

Commit

Permalink
Fix ConstantFloatType value dump precision
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Jun 7, 2023
1 parent db1d37e commit 707ada1
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 15 deletions.
31 changes: 20 additions & 11 deletions src/Type/Constant/ConstantFloatType.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
use PHPStan\Type\Type;
use PHPStan\Type\VerbosityLevel;
use function abs;
use function ini_get;
use function ini_set;
use function is_finite;
use function rtrim;
use function sprintf;
use function strpos;
use const PHP_FLOAT_EPSILON;

Expand Down Expand Up @@ -45,18 +45,27 @@ public function equals(Type $type): bool
return $type instanceof self && abs($this->value - $type->value) < PHP_FLOAT_EPSILON;
}

private function castFloatToString(float $value): string
{
$precisionBackup = ini_get('precision');
ini_set('precision', '-1');
try {
$valueStr = (string) $value;
if (is_finite($value) && strpos($valueStr, '.') === false) {
$valueStr .= '.0';
}

return $valueStr;
} finally {
ini_set('precision', $precisionBackup);
}
}

public function describe(VerbosityLevel $level): string
{
return $level->handle(
static fn (): string => 'float',
function (): string {
$formatted = (string) $this->value;
if (is_finite($this->value) && strpos($formatted, '.') === false) {
$formatted .= '.0';
}

return $formatted;
},
fn (): string => $this->castFloatToString($this->value),
);
}

Expand Down Expand Up @@ -110,7 +119,7 @@ public function generalize(GeneralizePrecision $precision): Type
*/
public function toPhpDocNode(): TypeNode
{
return new ConstTypeNode(new ConstExprFloatNode(rtrim(rtrim(sprintf('%.20f', $this->value), '0'), '.')));
return new ConstTypeNode(new ConstExprFloatNode($this->castFloatToString($this->value)));
}

/**
Expand Down
8 changes: 8 additions & 0 deletions tests/PHPStan/Type/Constant/ConstantFloatTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ public function dataDescribe(): array
new ConstantFloatType(1.2000000992884E-10),
'1.2000000992884E-10',
],
[
new ConstantFloatType(-1.200000099288476E+10),
'-12000000992.88476',
],
[
new ConstantFloatType(-1.200000099288476E+20),
'-1.200000099288476E+20',
],
[
new ConstantFloatType(1.2 * 1.4),
'1.68',
Expand Down
45 changes: 41 additions & 4 deletions tests/PHPStan/Type/TypeToPhpDocNodeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
use PHPStan\Type\Generic\GenericObjectType;
use stdClass;
use function sprintf;
use const PHP_INT_MAX;
use const PHP_INT_MIN;

class TypeToPhpDocNodeTest extends PHPStanTestCase
{
Expand Down Expand Up @@ -311,24 +313,59 @@ public function dataToPhpDocNodeWithoutCheckingEquals(): iterable
'(literal-string & non-falsy-string)',
];

yield [
new ConstantIntegerType(PHP_INT_MIN),
(string) PHP_INT_MIN,
];

yield [
new ConstantIntegerType(PHP_INT_MAX),
(string) PHP_INT_MAX,
];

yield [
new ConstantFloatType(9223372036854775807),
'9223372036854775808',
'9.223372036854776E+18',
];

yield [
new ConstantFloatType(-9223372036854775808),
'-9223372036854775808',
'-9.223372036854776E+18',
];

yield [
new ConstantFloatType(2.35),
'2.35000000000000008882',
'2.35',
];

yield [
new ConstantFloatType(100),
'100',
'100.0',
];

yield [
new ConstantFloatType(8.202343767574732),
'8.202343767574732',
];

yield [
new ConstantFloatType(1e80),
'1.0E+80',
];

yield [
new ConstantFloatType(-5e-80),
'-5.0E-80',
];

yield [
new ConstantFloatType(0.0),
'0.0',
];

yield [
new ConstantFloatType(-0.0),
'-0.0',
];
}

Expand Down

0 comments on commit 707ada1

Please sign in to comment.