Skip to content

Commit

Permalink
Add BigInteger::mod()
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMorel committed Jan 21, 2020
1 parent 32e67c9 commit 73f3ca7
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 0 deletions.
27 changes: 27 additions & 0 deletions src/BigInteger.php
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ public function quotient($that) : BigInteger
/**
* Returns the remainder of the division of this number by the given one.
*
* The remainder, when non-zero, has the same sign as the dividend.
*
* @param BigNumber|number|string $that The divisor. Must be convertible to a BigInteger.
*
* @return BigInteger
Expand Down Expand Up @@ -413,6 +415,31 @@ public function quotientAndRemainder($that) : array
];
}

/**
* Returns the modulo of this number and the given one.
*
* The modulo operation yields the same result as the remainder operation when both operands are of the same sign,
* and may differ when signs are different.
*
* The result of the modulo operation, when non-zero, has the same sign as the divisor.
*
* @param BigNumber|number|string $that The divisor. Must be convertible to a BigInteger.
*
* @return BigInteger
*
* @throws DivisionByZeroException If the divisor is zero.
*/
public function mod($that) : BigInteger
{
$that = BigInteger::of($that);

if ($that->value === '0') {
throw DivisionByZeroException::divisionByZero();
}

return $this->remainder($that)->plus($that)->remainder($that);
}

/**
* Returns the greatest common divisor of this number and the given one.
*
Expand Down
99 changes: 99 additions & 0 deletions tests/BigIntegerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,8 @@ public function providerQuotientAndRemainder()
['-1', '123', '0', '-1'],
['-1', '-123', '0', '-1'],

['-21', '4', '-5', '-1'],

['1999999999999999999999999', '2000000000000000000000000', '0', '1999999999999999999999999'],
['1999999999999999999999999', '-2000000000000000000000000', '0', '1999999999999999999999999'],
['-1999999999999999999999999', '2000000000000000000000000', '0', '-1999999999999999999999999'],
Expand Down Expand Up @@ -1299,6 +1301,103 @@ public function testQuotientAndRemainderByZeroThrowsException()
BigInteger::of(1)->quotientAndRemainder(0);
}

/**
* @dataProvider providerMod
*/
public function testMod(string $dividend, string $divisor, string $expected) : void
{
$this->assertBigIntegerEquals($expected, BigInteger::of($dividend)->mod($divisor));
}

public function providerMod() : array
{
return [
['0', '1', '0'],
['0', '-1', '0'],

['1', '123', '1'],
['1', '-123', '-122'],
['-1', '123', '122'],
['-1', '-123', '-1'],

['2', '7', '2'],
['2', '-7', '-5'],
['-2', '7', '5'],
['-2', '-7', '-2'],

['12', '7', '5'],
['12', '-7', '-2'],
['-12', '7', '2'],
['-12', '-7', '-5'],

['123', '1', '0'],
['123', '-1', '0'],
['-123', '1', '0'],
['-123', '-1', '0'],

['123', '2', '1'],
['123', '-2', '-1'],
['-123', '2', '1'],
['-123', '-2', '-1'],

['123', '123', '0'],
['123', '-123', '0'],
['-123', '123', '0'],
['-123', '-123', '0'],

['123', '124', '123'],
['123', '-124', '-1'],
['-123', '124', '1'],
['-123', '-124', '-123'],

['124', '123', '1'],
['124', '-123', '-122'],
['-124', '123', '122'],
['-124', '-123', '-1'],

['100000000', '353467', '322306'],
['100000000', '-353467', '-31161'],
['-100000000', '353467', '31161'],
['-100000000', '-353467', '-322306'],

['1999999999999999999999999', '2000000000000000000000000', '1999999999999999999999999'],
['1999999999999999999999999', '-2000000000000000000000000', '-1'],
['-1999999999999999999999999', '2000000000000000000000000', '1'],
['-1999999999999999999999999', '-2000000000000000000000000', '-1999999999999999999999999'],

['1000000000000000000000000000000', '3', '1'],
['1000000000000000000000000000000', '-3', '-2'],
['1000000000000000000000000000000', '9', '1'],
['1000000000000000000000000000000', '-9', '-8'],
['1000000000000000000000000000000', '11', '1'],
['1000000000000000000000000000000', '-11', '-10'],
['1000000000000000000000000000000', '13', '1'],
['1000000000000000000000000000000', '-13', '-12'],
['1000000000000000000000000000000', '21', '1'],
['1000000000000000000000000000000', '-21', '-20'],

['123456789123456789123456789', '987654321987654321', '850308642973765431'],
['123456789123456789123456789', '-87654321987654321', '-22030924930968528'],
['-123456789123456789123456789', '7654321987654321', '5820145655913952'],
['-123456789123456789123456789', '-654321987654321', '-205094497790673'],

['123456789098765432101234567890987654321', '1', '0'],
['123456789098765432101234567890987654321', '-1', '0'],
['1282493059039502950823948435791053205342314', '24342491090593053', '4167539367989094'],
['1000000000000000000000000000000000000000000000', '7777777777777777', '2232222222222222'],
['999999999999999999999999999999999999999999999', '22221222222', '13737242865'],
['49283205308081983923480483094304390249024223', '-23981985358744892239240813', '-3262726521512570595385995'],
['-8378278174814983902084304176539029302438924', '384758527893793829309012129991', '17174256549949655473639464372'],
['-444444444444444444444444444444444444411111', '-33333333333333', '-33333333300000'],
];
}

public function testModZeroThrowsException() : void
{
$this->expectException(DivisionByZeroException::class);
BigInteger::of(1)->mod(0);
}

/**
* @dataProvider providerPower
*
Expand Down

0 comments on commit 73f3ca7

Please sign in to comment.