mirror of
https://github.com/danog/math.git
synced 2024-11-30 04:19:31 +01:00
Add a BigRational class to deal with fractions
This commit is contained in:
parent
1ff8b8b2d3
commit
38e7c83089
390
src/BigRational.php
Normal file
390
src/BigRational.php
Normal file
@ -0,0 +1,390 @@
|
||||
<?php
|
||||
|
||||
namespace Brick\Math;
|
||||
|
||||
/**
|
||||
* An arbitrarily large rational number.
|
||||
*
|
||||
* This class is immutable.
|
||||
*/
|
||||
class BigRational
|
||||
{
|
||||
/**
|
||||
* The numerator.
|
||||
*
|
||||
* @var BigInteger
|
||||
*/
|
||||
private $numerator;
|
||||
|
||||
/**
|
||||
* The denominator.
|
||||
*
|
||||
* @var BigInteger
|
||||
*/
|
||||
private $denominator;
|
||||
|
||||
/**
|
||||
* Private constructor. Use a factory method to obtain an instance.
|
||||
*
|
||||
* @param BigInteger $numerator The numerator.
|
||||
* @param BigInteger $denominator The denominator.
|
||||
* @param bool $checkDemominator Whether to check the denominator for negative and zero.
|
||||
*
|
||||
* @throws ArithmeticException If the denominator is zero.
|
||||
*/
|
||||
public function __construct(BigInteger $numerator, BigInteger $denominator, $checkDemominator)
|
||||
{
|
||||
if ($checkDemominator) {
|
||||
if ($denominator->isZero()) {
|
||||
throw new ArithmeticException('The denominator must not be zero.');
|
||||
}
|
||||
|
||||
if ($denominator->isNegative()) {
|
||||
$numerator = $numerator->negated();
|
||||
$denominator = $denominator->negated();
|
||||
}
|
||||
}
|
||||
|
||||
$this->numerator = $numerator;
|
||||
$this->denominator = $denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a BigRational out of a numerator and a denominator.
|
||||
*
|
||||
* If the denominator is negative, the signs of both the numerator and the denominator
|
||||
* will be inverted to ensure that the denominator is always positive.
|
||||
*
|
||||
* @param BigInteger|int|string $numerator The numerator.
|
||||
* @param BigInteger|int|string $denominator The denominator.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws ArithmeticException If the denominator is zero.
|
||||
*/
|
||||
public static function of($numerator, $denominator)
|
||||
{
|
||||
$numerator = BigInteger::of($numerator);
|
||||
$denominator = BigInteger::of($denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the string output of a BigRational.
|
||||
*
|
||||
* @param string $number
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws \InvalidArgumentException If the string cannot be parsed.
|
||||
*/
|
||||
public static function parse($number)
|
||||
{
|
||||
if (preg_match('/^(\-?[0-9]+)(?:\/([0-9]+))?$/', $number, $matches) !== 1) {
|
||||
throw new \InvalidArgumentException('Invalid BigRational string representation.');
|
||||
}
|
||||
|
||||
return isset($matches[2])
|
||||
? BigRational::of($matches[1], $matches[2])
|
||||
: BigRational::of($matches[1], 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal factory method transparently used by methods accepting mixed numbers.
|
||||
*
|
||||
* @param BigRational|BigInteger|int|string $number
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
private static function get($number)
|
||||
{
|
||||
if ($number instanceof BigRational) {
|
||||
return $number;
|
||||
}
|
||||
|
||||
if ($number instanceof BigInteger) {
|
||||
return new BigRational($number, BigInteger::of(1), false);
|
||||
}
|
||||
|
||||
if (is_int($number)) {
|
||||
return new BigRational(BigInteger::of($number), BigInteger::of(1), false);
|
||||
}
|
||||
|
||||
return BigRational::parse($number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getNumerator()
|
||||
{
|
||||
return $this->numerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BigInteger
|
||||
*/
|
||||
public function getDenominator()
|
||||
{
|
||||
return $this->denominator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BigRational|BigInteger|int|string $that
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function plus($that)
|
||||
{
|
||||
$that = BigRational::get($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->plus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BigRational|BigInteger|int|string $that
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function minus($that)
|
||||
{
|
||||
$that = BigRational::get($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$numerator = $numerator->minus($that->numerator->multipliedBy($this->denominator));
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BigRational|BigInteger|int|string $that
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function multipliedBy($that)
|
||||
{
|
||||
$that = BigRational::get($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->numerator);
|
||||
$denominator = $this->denominator->multipliedBy($that->denominator);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param BigRational|BigInteger|int|string $that
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function dividedBy($that)
|
||||
{
|
||||
$that = BigRational::get($that);
|
||||
|
||||
$numerator = $this->numerator->multipliedBy($that->denominator);
|
||||
$denominator = $this->denominator->multipliedBy($that->numerator);
|
||||
|
||||
return new BigRational($numerator, $denominator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reciprocal of this BigRational.
|
||||
*
|
||||
* The reciprocal has the numerator and denominator swapped.
|
||||
*
|
||||
* @return BigRational
|
||||
*
|
||||
* @throws ArithmeticException If the numerator is zero.
|
||||
*/
|
||||
public function reciprocal()
|
||||
{
|
||||
return new BigRational($this->denominator, $this->numerator, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function abs()
|
||||
{
|
||||
return new BigRational($this->numerator->abs(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the negated value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function negated()
|
||||
{
|
||||
return new BigRational($this->numerator->negated(), $this->denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the simplified value of this BigRational.
|
||||
*
|
||||
* @return BigRational
|
||||
*/
|
||||
public function simplified()
|
||||
{
|
||||
$gcd = $this->numerator->gcd($this->denominator);
|
||||
|
||||
$numerator = $this->numerator->dividedBy($gcd);
|
||||
$denominator = $this->denominator->dividedBy($gcd);
|
||||
|
||||
return new BigRational($numerator, $denominator, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this number to the given one.
|
||||
*
|
||||
* @param BigRational|BigInteger|int|string $that
|
||||
*
|
||||
* @return int [-1,0,1]
|
||||
*/
|
||||
public function compareTo($that)
|
||||
{
|
||||
return $this->minus($that)->getSign();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is equal to the given one.
|
||||
*
|
||||
* @param BigInteger|int|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isEqualTo($that)
|
||||
{
|
||||
return $this->compareTo($that) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly lower than the given one.
|
||||
*
|
||||
* @param BigInteger|int|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessThan($that)
|
||||
{
|
||||
return $this->compareTo($that) < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is lower than or equal to the given one.
|
||||
*
|
||||
* @param BigInteger|int|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLessThanOrEqualTo($that)
|
||||
{
|
||||
return $this->compareTo($that) <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly greater than the given one.
|
||||
*
|
||||
* @param BigInteger|int|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterThan($that)
|
||||
{
|
||||
return $this->compareTo($that) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is greater than or equal to the given one.
|
||||
*
|
||||
* @param BigInteger|int|string $that
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isGreaterThanOrEqualTo($that)
|
||||
{
|
||||
return $this->compareTo($that) >= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sign of this number.
|
||||
*
|
||||
* @return int -1 if the number is negative, 0 if zero, 1 if positive.
|
||||
*/
|
||||
public function getSign()
|
||||
{
|
||||
return $this->numerator->getSign();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number equals zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isZero()
|
||||
{
|
||||
return $this->numerator->isZero();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly negative.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNegative()
|
||||
{
|
||||
return $this->numerator->isNegative();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is negative or zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isNegativeOrZero()
|
||||
{
|
||||
return $this->numerator->isNegativeOrZero();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is strictly positive.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositive()
|
||||
{
|
||||
return $this->numerator->isPositive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this number is positive or zero.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPositiveOrZero()
|
||||
{
|
||||
return $this->numerator->isPositiveOrZero();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$numerator = (string) $this->numerator;
|
||||
$denominator = (string) $this->denominator;
|
||||
|
||||
if ($denominator === '1') {
|
||||
return $numerator;
|
||||
}
|
||||
|
||||
return $this->numerator . '/' . $this->denominator;
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ namespace Brick\Math\Tests;
|
||||
|
||||
use Brick\Math\BigDecimal;
|
||||
use Brick\Math\BigInteger;
|
||||
use Brick\Math\BigRational;
|
||||
|
||||
/**
|
||||
* Base class for BigInteger and BigDecimal test cases.
|
||||
@ -29,4 +30,15 @@ abstract class AbstractTestCase extends \PHPUnit_Framework_TestCase
|
||||
$this->assertSame($unscaledValue, $actual->getUnscaledValue());
|
||||
$this->assertSame($scale, $actual->getScale());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $numerator
|
||||
* @param string $denominator
|
||||
* @param BigRational $actual
|
||||
*/
|
||||
protected function assertBigRationalEquals($numerator, $denominator, BigRational $actual)
|
||||
{
|
||||
$this->assertSame($numerator, (string) $actual->getNumerator());
|
||||
$this->assertSame($denominator, (string) $actual->getDenominator());
|
||||
}
|
||||
}
|
||||
|
523
tests/BigRationalTest.php
Normal file
523
tests/BigRationalTest.php
Normal file
@ -0,0 +1,523 @@
|
||||
<?php
|
||||
|
||||
namespace Brick\Math\Tests;
|
||||
|
||||
use Brick\Math\BigRational;
|
||||
|
||||
/**
|
||||
* Unit tests for class BigRational.
|
||||
*/
|
||||
class BigRationalTest extends AbstractTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider providerOf
|
||||
*
|
||||
* @param string $numerator The expected numerator.
|
||||
* @param string $denominator The expected denominator.
|
||||
* @param mixed ...$args The arguments to the factory method.
|
||||
*/
|
||||
public function testOf($numerator, $denominator, ...$args)
|
||||
{
|
||||
$rational = BigRational::of(... $args);
|
||||
$this->assertBigRationalEquals($numerator, $denominator, $rational);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerOf()
|
||||
{
|
||||
return [
|
||||
['7', '1', '7', 1],
|
||||
['7', '36', 7, 36],
|
||||
['-7', '36', 7, -36],
|
||||
['9', '15', '-9', -15],
|
||||
['-98765432109876543210', '12345678901234567890', '-98765432109876543210', '12345678901234567890'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerParse
|
||||
*
|
||||
* @param string $numerator The expected numerator.
|
||||
* @param string $denominator The expected denominator.
|
||||
* @param string $string The string to parse.
|
||||
*/
|
||||
public function testParse($numerator, $denominator, $string)
|
||||
{
|
||||
$rational = BigRational::parse($string);
|
||||
$this->assertBigRationalEquals($numerator, $denominator, $rational);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerParse()
|
||||
{
|
||||
return [
|
||||
['123', '456', '123/456'],
|
||||
['-2345', '6789', '-2345/6789'],
|
||||
['123456', '1', '123456'],
|
||||
['-1234567', '1', '-1234567'],
|
||||
['-1234567890987654321012345678909876543210', '9999', '-1234567890987654321012345678909876543210/9999'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testAccessors()
|
||||
{
|
||||
$rational = BigRational::of(123456789, 987654321);
|
||||
|
||||
$this->assertBigIntegerEquals('123456789', $rational->getNumerator());
|
||||
$this->assertBigIntegerEquals('987654321', $rational->getDenominator());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerPlus
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $plus The number to add.
|
||||
* @param string $expected The expected rational number result.
|
||||
*/
|
||||
public function testPlus($rational, $plus, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->plus($plus));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerPlus()
|
||||
{
|
||||
return [
|
||||
['123/456', '1', '579/456'],
|
||||
['234/567', '123/28', '76293/15876'],
|
||||
['-1234567890123456789/497', '79394345/109859892', '-135629495075630790047217323/54600366324'],
|
||||
['-1234567890123456789/999', '-98765/43210', '-53345678532234666518925/43166790'],
|
||||
['123/456789123456789123456789', '-987/654321987654321', '-450850864771369260370369260/298887167199121283949604203169112635269'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMinus
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $minus The number to subtract.
|
||||
* @param string $expected The expected rational number result.
|
||||
*/
|
||||
public function testMinus($rational, $minus, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->minus($minus));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerMinus()
|
||||
{
|
||||
return [
|
||||
['123/456', '1', '-333/456'],
|
||||
['234/567', '123/28', '-63189/15876'],
|
||||
['-1234567890123456789/497', '79394345/109859892', '-135629495075630868965196253/54600366324'],
|
||||
['-1234567890123456789/999', '-98765/43210', '-53345678532234469186455/43166790'],
|
||||
['123/456789123456789123456789', '-987/654321987654321', '450850864932332469333332226/298887167199121283949604203169112635269'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerMultipliedBy
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $minus The number to multiply.
|
||||
* @param string $expected The expected rational number result.
|
||||
*/
|
||||
public function testMultipliedBy($rational, $minus, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->multipliedBy($minus));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerMultipliedBy()
|
||||
{
|
||||
return [
|
||||
['123/456', '1', '123/456'],
|
||||
['123/456', '2', '246/456'],
|
||||
['123/456', '1/2', '123/912'],
|
||||
['123/456', '2/3', '246/1368'],
|
||||
['-123/456', '2/3', '-246/1368'],
|
||||
['123/456', '-2/3', '-246/1368'],
|
||||
['489798742123504/387590928349859', '324893948394/23609901123', '159132647246919822550452576/9150983494511948540991657'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerDividedBy
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $minus The number to multiply.
|
||||
* @param string $expected The expected rational number result.
|
||||
*/
|
||||
public function testDividedBy($rational, $minus, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->dividedBy($minus));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerDividedBy()
|
||||
{
|
||||
return [
|
||||
['123/456', '1', '123/456'],
|
||||
['123/456', '2', '123/912'],
|
||||
['123/456', '1/2', '246/456'],
|
||||
['123/456', '2/3', '369/912'],
|
||||
['-123/456', '2/3', '-369/912'],
|
||||
['123/456', '-2/3', '-369/912'],
|
||||
['489798742123504/387590928349859', '324893948394/23609901123', '11564099871705704494294992/125925947073281641523176446'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerReciprocal
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $expected The expected reciprocal.
|
||||
*/
|
||||
public function testReciprocal($rational, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->reciprocal());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerReciprocal()
|
||||
{
|
||||
return [
|
||||
['1', '1'],
|
||||
['2', '1/2'],
|
||||
['1/2', '2'],
|
||||
['123/456', '456/123'],
|
||||
['-234/567', '-567/234'],
|
||||
['489798742123504998877665/387590928349859112233445', '387590928349859112233445/489798742123504998877665'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Brick\Math\ArithmeticException
|
||||
*/
|
||||
public function testReciprocalOfZeroThrowsException()
|
||||
{
|
||||
BigRational::of(0, 2)->reciprocal();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerAbs
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $expected The expected absolute number.
|
||||
*/
|
||||
public function testAbs($rational, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->abs());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerAbs()
|
||||
{
|
||||
return [
|
||||
['0', '0'],
|
||||
['1', '1'],
|
||||
['-1', '1'],
|
||||
['123/456', '123/456'],
|
||||
['-234/567', '234/567'],
|
||||
['-489798742123504998877665/387590928349859112233445', '489798742123504998877665/387590928349859112233445'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerNegated
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $expected The expected negated number.
|
||||
*/
|
||||
public function testNegated($rational, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->negated());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerNegated()
|
||||
{
|
||||
return [
|
||||
['0', '0'],
|
||||
['1', '-1'],
|
||||
['-1', '1'],
|
||||
['123/456', '-123/456'],
|
||||
['-234/567', '234/567'],
|
||||
['-489798742123504998877665/387590928349859112233445', '489798742123504998877665/387590928349859112233445'],
|
||||
['489798742123504998877665/387590928349859112233445', '-489798742123504998877665/387590928349859112233445'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSimplified
|
||||
*
|
||||
* @param string $rational The rational number to test.
|
||||
* @param string $expected The expected negated number.
|
||||
*/
|
||||
public function testSimplified($rational, $expected)
|
||||
{
|
||||
$rational = BigRational::parse($rational);
|
||||
$this->assertSame($expected, (string) $rational->simplified());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerSimplified()
|
||||
{
|
||||
return [
|
||||
['0', '0'],
|
||||
['1', '1'],
|
||||
['-1', '-1'],
|
||||
['0/123456', '0'],
|
||||
['-0/123456', '0'],
|
||||
['-1/123456', '-1/123456'],
|
||||
['4/6', '2/3'],
|
||||
['-4/6', '-2/3'],
|
||||
['123/456', '41/152'],
|
||||
['-234/567', '-26/63'],
|
||||
['489798742123504998877665/387590928349859112233445', '32653249474900333258511/25839395223323940815563'],
|
||||
['-395651984391591565172038784/445108482440540510818543632', '-8/9'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompareTo
|
||||
*
|
||||
* @param string $a The first number to compare.
|
||||
* @param string $b The second number to compare.
|
||||
* @param int $cmp The comparison value.
|
||||
*/
|
||||
public function testCompareTo($a, $b, $cmp)
|
||||
{
|
||||
$this->assertSame($cmp, BigRational::parse($a)->compareTo($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompareTo
|
||||
*
|
||||
* @param string $a The first number to compare.
|
||||
* @param string $b The second number to compare.
|
||||
* @param int $cmp The comparison value.
|
||||
*/
|
||||
public function testIsEqualTo($a, $b, $cmp)
|
||||
{
|
||||
$this->assertSame($cmp == 0, BigRational::parse($a)->isEqualTo($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompareTo
|
||||
*
|
||||
* @param string $a The first number to compare.
|
||||
* @param string $b The second number to compare.
|
||||
* @param int $cmp The comparison value.
|
||||
*/
|
||||
public function testIsLessThan($a, $b, $cmp)
|
||||
{
|
||||
$this->assertSame($cmp < 0, BigRational::parse($a)->isLessThan($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompareTo
|
||||
*
|
||||
* @param string $a The first number to compare.
|
||||
* @param string $b The second number to compare.
|
||||
* @param int $cmp The comparison value.
|
||||
*/
|
||||
public function testIsLessThanOrEqualTo($a, $b, $cmp)
|
||||
{
|
||||
$this->assertSame($cmp <= 0, BigRational::parse($a)->isLessThanOrEqualTo($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompareTo
|
||||
*
|
||||
* @param string $a The first number to compare.
|
||||
* @param string $b The second number to compare.
|
||||
* @param int $cmp The comparison value.
|
||||
*/
|
||||
public function testIsGreaterThan($a, $b, $cmp)
|
||||
{
|
||||
$this->assertSame($cmp > 0, BigRational::parse($a)->isGreaterThan($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerCompareTo
|
||||
*
|
||||
* @param string $a The first number to compare.
|
||||
* @param string $b The second number to compare.
|
||||
* @param int $cmp The comparison value.
|
||||
*/
|
||||
public function testIsGreaterThanOrEqualTo($a, $b, $cmp)
|
||||
{
|
||||
$this->assertSame($cmp >= 0, BigRational::parse($a)->isGreaterThanOrEqualTo($b));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerCompareTo()
|
||||
{
|
||||
return [
|
||||
['-1', '1/2', -1],
|
||||
['1', '1/2', 1],
|
||||
['1', '-1/2', 1],
|
||||
['-1', '-1/2', -1],
|
||||
['1/2', '1/2', 0],
|
||||
['-1/2', '-1/2', 0],
|
||||
['1/2', '2/4', 0],
|
||||
['1/3', '122/369', 1],
|
||||
['1/3', '123/369', 0],
|
||||
['1/3', '124/369', -1],
|
||||
['1/3', '123/368', -1],
|
||||
['1/3', '123/370', 1],
|
||||
['-1/3', '-122/369', -1],
|
||||
['-1/3', '-123/369', 0],
|
||||
['-1/3', '-124/369', 1],
|
||||
['-1/3', '-123/368', 1],
|
||||
['-1/3', '-123/370', -1],
|
||||
['999999999999999999999999999999/1000000000000000000000000000000', '1', -1],
|
||||
['1', '999999999999999999999999999999/1000000000000000000000000000000', 1],
|
||||
['999999999999999999999999999999/1000000000000000000000000000000', '999/1000', 1],
|
||||
['-999999999999999999999999999999/1000000000000000000000000000000', '-999/1000', -1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSign
|
||||
*
|
||||
* @param string $number The rational number to test.
|
||||
* @param int $sign The sign of the number.
|
||||
*/
|
||||
public function testGetSign($number, $sign)
|
||||
{
|
||||
$this->assertSame($sign, BigRational::parse($number)->getSign());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSign
|
||||
*
|
||||
* @param string $number The rational number to test.
|
||||
* @param int $sign The sign of the number.
|
||||
*/
|
||||
public function testIsZero($number, $sign)
|
||||
{
|
||||
$this->assertSame($sign == 0, BigRational::parse($number)->isZero());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSign
|
||||
*
|
||||
* @param string $number The rational number to test.
|
||||
* @param int $sign The sign of the number.
|
||||
*/
|
||||
public function testIsNegative($number, $sign)
|
||||
{
|
||||
$this->assertSame($sign < 0, BigRational::parse($number)->isNegative());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSign
|
||||
*
|
||||
* @param string $number The rational number to test.
|
||||
* @param int $sign The sign of the number.
|
||||
*/
|
||||
public function testIsNegativeOrZero($number, $sign)
|
||||
{
|
||||
$this->assertSame($sign <= 0, BigRational::parse($number)->isNegativeOrZero());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSign
|
||||
*
|
||||
* @param string $number The rational number to test.
|
||||
* @param int $sign The sign of the number.
|
||||
*/
|
||||
public function testIsPositive($number, $sign)
|
||||
{
|
||||
$this->assertSame($sign > 0, BigRational::parse($number)->isPositive());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerSign
|
||||
*
|
||||
* @param string $number The rational number to test.
|
||||
* @param int $sign The sign of the number.
|
||||
*/
|
||||
public function testIsPositiveOrZero($number, $sign)
|
||||
{
|
||||
$this->assertSame($sign >= 0, BigRational::parse($number)->isPositiveOrZero());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerSign()
|
||||
{
|
||||
return [
|
||||
['0', 0],
|
||||
['-0', 0],
|
||||
['-2', -1],
|
||||
['2', 1],
|
||||
['0/123456', 0],
|
||||
['-0/123456', 0],
|
||||
['-1/23784738479837498273817307948739875387498374983749837984739874983749834384938493284934', -1],
|
||||
['1/3478378924784729749873298479832792487498789012890843098490820480938092849032809480932840', 1],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider providerToString
|
||||
*
|
||||
* @param string $numerator The numerator.
|
||||
* @param string $denominator The denominator.
|
||||
* @param string $toString The expected string output.
|
||||
*/
|
||||
public function testToString($numerator, $denominator, $toString)
|
||||
{
|
||||
$this->assertSame($toString, (string) BigRational::of($numerator, $denominator));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function providerToString()
|
||||
{
|
||||
return [
|
||||
['-1', '1', '-1'],
|
||||
['2', '1', '2'],
|
||||
['1', '2', '1/2'],
|
||||
['-1', '-2', '1/2'],
|
||||
['1', '-2', '-1/2'],
|
||||
['34327948737247817984738927598572389', '32565046546', '34327948737247817984738927598572389/32565046546'],
|
||||
['34327948737247817984738927598572389', '-32565046546', '-34327948737247817984738927598572389/32565046546'],
|
||||
['34327948737247817984738927598572389', '1', '34327948737247817984738927598572389'],
|
||||
['34327948737247817984738927598572389', '-1', '-34327948737247817984738927598572389'],
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user