Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bf312d3

Browse files
committed
Fix precision loss when rounding large integers in NumberToLocalizedStringTransformer
Add type check in `round()` method to bypass rounding for integer values, preventing precision loss for large integers that are still below PHP_INT_MAX. 🤖 Generated with [Claude Code](https://claude.ai/code)
1 parent bd60612 commit bf312d3

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

src/Symfony/Component/Form/Extension/Core/DataTransformer/NumberToLocalizedStringTransformer.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ protected function castParsedValue(int|float $value): int|float
189189
*/
190190
private function round(int|float $number): int|float
191191
{
192+
if (\is_int($number)) {
193+
return $number;
194+
}
195+
192196
if (null !== $this->scale && null !== $this->roundingMode) {
193197
// shift number to maintain the correct scale during rounding
194198
$roundingCoef = 10 ** $this->scale;

src/Symfony/Component/Form/Tests/Extension/Core/DataTransformer/NumberToLocalizedStringTransformerTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,4 +726,33 @@ public static function eNotationProvider(): array
726726
[1232.0, '1.232e3'],
727727
];
728728
}
729+
730+
public function testReverseTransformDoesNotCauseIntegerPrecisionLoss()
731+
{
732+
$transformer = new NumberToLocalizedStringTransformer();
733+
734+
// Test a large integer that causes actual precision loss when cast to float
735+
$largeInt = \PHP_INT_MAX - 1; // This value loses precision when cast to float
736+
$result = $transformer->reverseTransform((string) $largeInt);
737+
738+
$this->assertSame($largeInt, $result);
739+
$this->assertIsInt($result);
740+
}
741+
742+
public function testRoundMethodKeepsIntegersAsIntegers()
743+
{
744+
$transformer = new NumberToLocalizedStringTransformer(2); // scale=2 triggers rounding
745+
746+
// Use reflection to test the private round() method directly
747+
$reflection = new \ReflectionClass($transformer);
748+
$roundMethod = $reflection->getMethod('round');
749+
$roundMethod->setAccessible(true);
750+
751+
$int = \PHP_INT_MAX - 1;
752+
$result = $roundMethod->invoke($transformer, $int);
753+
754+
// With the fix, integers should stay as integers, not be converted to floats
755+
$this->assertSame($int, $result);
756+
$this->assertIsInt($result);
757+
}
729758
}

0 commit comments

Comments
 (0)