[Validator] Fix precision issue regarding floats and DivisibleBy constraint

This commit is contained in:
Jannik Zschiesche 2018-08-16 18:51:30 +02:00 committed by Nicolas Grekas
parent 71794f4fc4
commit ae04b48332
2 changed files with 14 additions and 1 deletions

View File

@ -23,7 +23,17 @@ class DivisibleByValidator extends AbstractComparisonValidator
*/ */
protected function compareValues($value1, $value2) protected function compareValues($value1, $value2)
{ {
return (float) 0 === fmod($value1, $value2); if (!$value2 = abs($value2)) {
return false;
}
if (\is_int($value1 = abs($value1)) && \is_int($value2)) {
return 0 === ($value1 % $value2);
}
if (!$remainder = fmod($value1, $value2)) {
return true;
}
return sprintf('%.12e', $value2) === sprintf('%.12e', $remainder);
} }
/** /**

View File

@ -46,6 +46,8 @@ class DivisibleByValidatorTest extends AbstractComparisonValidatorTestCase
array(42, 21), array(42, 21),
array(3.25, 0.25), array(3.25, 0.25),
array('100', '10'), array('100', '10'),
array(4.1, 0.1),
array(-4.1, 0.1),
); );
} }
@ -69,6 +71,7 @@ class DivisibleByValidatorTest extends AbstractComparisonValidatorTestCase
array(10, '10', 3, '3', 'integer'), array(10, '10', 3, '3', 'integer'),
array(10, '10', 0, '0', 'integer'), array(10, '10', 0, '0', 'integer'),
array(42, '42', INF, 'INF', 'double'), array(42, '42', INF, 'INF', 'double'),
array(4.15, '4.15', 0.1, '0.1', 'double'),
array('22', '"22"', '10', '"10"', 'string'), array('22', '"22"', '10', '"10"', 'string'),
); );
} }