From 7ad04145dab7e24648399a07283d32ab38137c68 Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Thu, 16 Aug 2018 18:51:30 +0200 Subject: [PATCH 1/3] Fix several issues regarding floats and DivisibleBy validator --- .../Constraints/DivisibleByValidator.php | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php b/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php index c9455d71a17ef..b3f769c08cf3f 100644 --- a/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php @@ -23,7 +23,29 @@ class DivisibleByValidator extends AbstractComparisonValidator */ protected function compareValues($value1, $value2) { - return (float) 0 === fmod($value1, $value2); + $value1 = \abs($value1); + $value2 = \abs($value2); + $epsilon = 0.0000001; + + // can't divide by 0 + if ($value2 < $epsilon) + { + return false; + } + + // 0 is divisible by everything + if ($value1 < $epsilon) + { + return true; + } + + // if the divisor is larger than the dividend, it will never cleanly divide + if ($value2 > $value1) + { + return false; + } + + return \abs($value1 - round($value1 / $value2) * $value2) < $epsilon; } /** From 09912216134849de2f808acedd65ca40a450c0de Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Thu, 16 Aug 2018 18:54:21 +0200 Subject: [PATCH 2/3] Add test cases for additional DivisibleBy cases --- .../Validator/Tests/Constraints/DivisibleByValidatorTest.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Symfony/Component/Validator/Tests/Constraints/DivisibleByValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/DivisibleByValidatorTest.php index b4812ca8d5c55..117f0ef1f401b 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/DivisibleByValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/DivisibleByValidatorTest.php @@ -46,6 +46,7 @@ public function provideValidComparisons() array(42, 21), array(3.25, 0.25), array('100', '10'), + array(4.1, 0.1), ); } @@ -69,6 +70,7 @@ public function provideInvalidComparisons() array(10, '10', 3, '3', 'integer'), array(10, '10', 0, '0', 'integer'), array(42, '42', INF, 'INF', 'double'), + array(4.15, '4.15', 0.1, '0.1', 'double'), array('22', '"22"', '10', '"10"', 'string'), ); } From c0d69441d8b39f4337f8b002050f548902d25f4e Mon Sep 17 00:00:00 2001 From: Jannik Zschiesche Date: Thu, 16 Aug 2018 19:08:37 +0200 Subject: [PATCH 3/3] Fix CS --- .../Validator/Constraints/DivisibleByValidator.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php b/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php index b3f769c08cf3f..a64ad7be437a8 100644 --- a/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php +++ b/src/Symfony/Component/Validator/Constraints/DivisibleByValidator.php @@ -28,20 +28,17 @@ protected function compareValues($value1, $value2) $epsilon = 0.0000001; // can't divide by 0 - if ($value2 < $epsilon) - { + if ($value2 < $epsilon) { return false; } // 0 is divisible by everything - if ($value1 < $epsilon) - { + if ($value1 < $epsilon) { return true; } // if the divisor is larger than the dividend, it will never cleanly divide - if ($value2 > $value1) - { + if ($value2 > $value1) { return false; }