From 7563926255041774a2a7cb103d83f17d2bfe33a7 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Sat, 11 Sep 2021 20:39:12 +0900 Subject: [PATCH 1/3] Use smaller epsilon and relative error for float comparison Fixes #1537 --- .../JUnit/TestLocationBucketSorterTest.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php index 442ef7200..9b4af0f80 100644 --- a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php +++ b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php @@ -189,7 +189,7 @@ public function test_it_sorts_faster_than_quicksort(ArrayIterator $uniqueTestLoc $totalQuickSort += microtime(true) - $start; } - $this->assertGreaterThanOrEqual(0.01, abs($totalQuickSort - $totalBucketSort)); + $this->assertGreaterThanOrEqual(0.001, self::getRelativeError($totalQuickSort, $totalBucketSort)); } public static function locationsArrayProvider(): iterable @@ -206,6 +206,22 @@ static function (float $executionTime): TestLocation { yield 'All locations' => [new ArrayIterator($locations)]; } + /** + * Finds relative error. + * + * @see https://floating-point-gui.de/errors/comparison/ + * @see https://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison + */ + private static function getRelativeError(float $a, float $b): float + { + // We do not expect A or B to be extremely small or large: these are edge cases, + // and they will need special handling which we avoid simplicity sake. + self::assertGreaterThan(0.0001, abs($a)); + self::assertGreaterThan(0.0001, abs($b)); + + return abs($a - $b) / (abs($a) + abs($b)); + } + private static function quicksort(&$uniqueTestLocations): void { usort( From 5244bf7f8b501f37dcc7d040ff9c0da815506a87 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Sat, 11 Sep 2021 20:42:30 +0900 Subject: [PATCH 2/3] Use common epsilon here and there --- .../Coverage/JUnit/TestLocationBucketSorterTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php index 9b4af0f80..973330403 100644 --- a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php +++ b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php @@ -59,6 +59,8 @@ */ final class TestLocationBucketSorterTest extends TestCase { + private const EPSILON = 0.001; + public function test_it_sorts(): void { $testLocation = new TestLocation('', '', 0.0); @@ -189,7 +191,7 @@ public function test_it_sorts_faster_than_quicksort(ArrayIterator $uniqueTestLoc $totalQuickSort += microtime(true) - $start; } - $this->assertGreaterThanOrEqual(0.001, self::getRelativeError($totalQuickSort, $totalBucketSort)); + $this->assertGreaterThanOrEqual(self::EPSILON, self::getRelativeError($totalQuickSort, $totalBucketSort)); } public static function locationsArrayProvider(): iterable @@ -216,8 +218,8 @@ private static function getRelativeError(float $a, float $b): float { // We do not expect A or B to be extremely small or large: these are edge cases, // and they will need special handling which we avoid simplicity sake. - self::assertGreaterThan(0.0001, abs($a)); - self::assertGreaterThan(0.0001, abs($b)); + self::assertGreaterThan(self::EPSILON, abs($a)); + self::assertGreaterThan(self::EPSILON, abs($b)); return abs($a - $b) / (abs($a) + abs($b)); } From 62811fb1660a6d7d13cdf137a114627b04e9ccd7 Mon Sep 17 00:00:00 2001 From: Alexey Kopytko Date: Sat, 11 Sep 2021 20:44:02 +0900 Subject: [PATCH 3/3] Document the constant --- .../Coverage/JUnit/TestLocationBucketSorterTest.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php index 973330403..61aa11ecf 100644 --- a/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php +++ b/tests/phpunit/TestFramework/Coverage/JUnit/TestLocationBucketSorterTest.php @@ -59,6 +59,11 @@ */ final class TestLocationBucketSorterTest extends TestCase { + /** + * Used for floating point comparisons. + * + * @var float + */ private const EPSILON = 0.001; public function test_it_sorts(): void