diff --git a/src/BigRational.php b/src/BigRational.php index 9f7ccae..4625781 100644 --- a/src/BigRational.php +++ b/src/BigRational.php @@ -429,7 +429,8 @@ public function toInt() : int */ public function toFloat() : float { - return $this->numerator->toFloat() / $this->denominator->toFloat(); + $simplified = $this->simplified(); + return $simplified->numerator->toFloat() / $simplified->denominator->toFloat(); } /** diff --git a/tests/BigRationalTest.php b/tests/BigRationalTest.php index 80985d5..5ebb0c1 100644 --- a/tests/BigRationalTest.php +++ b/tests/BigRationalTest.php @@ -892,6 +892,38 @@ public function providerToIntThrowsException() : array ]; } + public function testIdentityOperationResultsInDifferentToFloatValueWithoutSimplification() : void + { + $expectedValue = 11.46; + $conversionFactor = BigRational::of('0.45359237'); + $value = BigRational::of($expectedValue); + + $identicalValueAfterMathOperations = $value->multipliedBy($conversionFactor) + ->dividedBy($conversionFactor) + ->multipliedBy($conversionFactor) + ->dividedBy($conversionFactor) + ->multipliedBy($conversionFactor) + ->dividedBy($conversionFactor); + + self::assertSame($expectedValue, $identicalValueAfterMathOperations->toFloat()); + + // Assert that simplification is required and the test would fail without it + self::assertNotSame( + $expectedValue, + $identicalValueAfterMathOperations->getNumerator()->toFloat() / $identicalValueAfterMathOperations->getDenominator()->toFloat(), + ); + } + + public function testToFloatConversionPerformsSimplificationToPreventOverflow() : void + { + $int = BigInteger::of('1e4000'); + $val = BigRational::nd($int, $int); + + self::assertInfinite($val->getNumerator()->toFloat()); + // Assert that simplification is required and the test would fail without it + self::assertSame(1.0, $val->toFloat()); + } + /** * @dataProvider providerToFloat *