Closed
Description
Symfony version(s) affected: 3.4, 4.4, 5.0, ...
Description
When using the NumberType, the reverse transform method does:
if (false !== strpos($value, $decSep)) {
$type = \NumberFormatter::TYPE_DOUBLE;
} else {
$type = PHP_INT_SIZE === 8 ? \NumberFormatter::TYPE_INT64 : \NumberFormatter::TYPE_INT32;
}
Which means,
- If
1
is submitted, an int should be set. - If
1.0
is submitted, a float should be set.
But then, a private function round is called and does:
private function round($number)
{
if (null !== $this->scale && null !== $this->roundingMode) {
// shift number to maintain the correct scale during rounding
$roundingCoef = pow(10, $this->scale);
// string representation to avoid rounding errors, similar to bcmul()
$number = (string) ($number * $roundingCoef);
switch ($this->roundingMode) {
...
case self::ROUND_HALF_UP:
$number = round($number, 0, PHP_ROUND_HALF_UP);
break;
...
}
$number /= $roundingCoef;
}
return $number;
}
Which means,
- If
1
is submitted with scalenull
, an int will be set. - If
1
is submitted with scale0
, a float will be set. - If
1
is submitted with scale1
, a float will be set. - If
1.0
is submitted with scalenull
, a float will be set. - If
1.0
is submitted with scale0
, a float will be set. - If
1.0
is submitted with scale1
, a float will be set.
It's the same for IntegerToLocalizedStringTransformer since it extends NumberToLocalizedStringTransformer with scale 0.
Possible Solution
Update the private round function to cast the value to int if the scale is 0
.