Skip to content

Commit

Permalink
Add BigInteger::gcd()
Browse files Browse the repository at this point in the history
This computes the greatest common divisor of two large integers.
  • Loading branch information
BenMorel committed Jun 11, 2015
1 parent 1f577af commit 4f4b953
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 0 deletions.
24 changes: 24 additions & 0 deletions src/BigInteger.php
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,30 @@ public function power($exponent)
return new BigInteger(Calculator::get()->pow($this->value, $exponent));
}

/**
* Returns the greatest common divisor of this number and the given one.
*
* The GCD is always positive.
*
* @param BigInteger|int|string $that
*
* @return BigInteger
*/
public function gcd($that)
{
$that = BigInteger::of($that);

if ($that->isZero()) {
return $this->abs();
}

if ($this->isZero()) {
return $that->abs();
}

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

/**
* Returns the absolute value of this number.
*
Expand Down
103 changes: 103 additions & 0 deletions tests/BigIntegerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,109 @@ public function providerPowerWithInvalidExponentThrowsException()
];
}

/**
* @dataProvider providerGcd
*
* @param string $a The first number.
* @param string $b The second number.
* @param string $gcd The expected GCD.
*/
public function testGcd($a, $b, $gcd)
{
$a = BigInteger::of($a);
$b = BigInteger::of($b);

$this->assertBigIntegerEquals($gcd, $a->gcd($b));
}

/**
* @return \Generator
*/
public function providerGcd()
{
$tests = [
['0', '0', '0'],

['123456789123456789123456789123456789', '0', '123456789123456789123456789123456789'],
['123456789123456789123456789123456789', '1', '1'],
['123456789123456789123456789123456789', '2', '1'],
['123456789123456789123456789123456789', '3', '3'],
['123456789123456789123456789123456789', '4', '1'],
['123456789123456789123456789123456789', '5', '1'],
['123456789123456789123456789123456789', '6', '3'],
['123456789123456789123456789123456789', '7', '7'],
['123456789123456789123456789123456789', '8', '1'],
['123456789123456789123456789123456789', '9', '9'],
['123456789123456789123456789123456789', '10', '1'],
['123456789123456789123456789123456789', '11', '11'],
['123456789123456789123456789123456789', '12', '3'],
['123456789123456789123456789123456789', '13', '13'],
['123456789123456789123456789123456789', '14', '7'],
['123456789123456789123456789123456789', '15', '3'],
['123456789123456789123456789123456789', '16', '1'],
['123456789123456789123456789123456789', '17', '1'],
['123456789123456789123456789123456789', '18', '9'],
['123456789123456789123456789123456789', '19', '19'],
['123456789123456789123456789123456789', '20', '1'],
['123456789123456789123456789123456789', '100', '1'],
['123456789123456789123456789123456789', '101', '101'],
['123456789123456789123456789123456789', '102', '3'],
['123456789123456789123456789123456789', '103', '1'],
['123456789123456789123456789123456789', '104', '13'],
['123456789123456789123456789123456789', '105', '21'],
['123456789123456789123456789123456789', '985', '1'],
['123456789123456789123456789123456789', '986', '1'],
['123456789123456789123456789123456789', '987', '21'],
['123456789123456789123456789123456789', '988', '247'],
['123456789123456789123456789123456789', '989', '1'],
['123456789123456789123456789123456789', '990', '99'],
['123456789123456789123456789123456789', '10010', '1001'],
['123456789123456789123456789123456789', '10017', '63'],
['123456789123456789123456789123456789', '10089', '171'],
['123456789123456789123456789123456789', '10098', '99'],
['123456789123456789123456789123456789', '100035', '2223'],
['123456789123456789123456789123456789', '1000065', '627'],
['123456789123456789123456789123456789', '10000068', '39'],
['123456789123456789123456789123456789', '10001222', '7777'],
['123456789123456789123456789123456789', '10001277', '24453'],
['123456789123456789123456789123456789', '100005258', '157737'],
['123456789123456789123456789123456789', '100010001', '2702973'],
['123456789123456789123456789123456789', '100148202', '50074101'],
['123456789123456789123456789123456789', '100478469', '14354067'],
['123456789123456789123456789123456789', '123456789140121129', '8249681517'],
['123456789123456789123456789123456789', '123456789150891631', '1385459521'],
['123456789123456789123456789123456789', '123456789192058322', '6928754833'],
['123456789123456789123456789123456789', '123456789202361433', '1992342261'],
['123456789123456789123456789123456789', '999456789162772941', '20786264499'],
['123456789123456789123456789123456789', '999456789176548074', '2345678991'],
['123456789123456789123456789123456789', '999456789188938248', '2372170689'],

['88888777776666655555444443333322222111110000099999', '100000000011886128', '8252579097'],
['88888777776666655555444443333322222111110000099999', '100000000013330403', '1162443303'],
['88888777776666655555444443333322222111110000099999', '100000000020221920', '2470053077'],
['88888777776666655555444443333322222111110000099999', '100000000031937250', '3970893353'],
['88888777776666655555444443333322222111110000099999', '100000000043341848', '1102420413'],
['88888777776666655555444443333322222111110000099999', '100000000047565681', '1212240071'],
['88888777776666655555444443333322222111110000099999', '100000000065586124', '1172302873'],
['88888777776666655555444443333322222111110000099999', '100000000068684846', '1051734417'],
['88888777776666655555444443333322222111110000099999', '100000000068736887', '2423071539'],
];

foreach ($tests as list ($a, $b, $gcd)) {
yield [$a, $b, $gcd];
yield [$b, $a, $gcd];

yield [$a, "-$b", $gcd];
yield [$b, "-$a", $gcd];

yield ["-$a", $b, $gcd];
yield ["-$b", $a, $gcd];

yield ["-$a", "-$b", $gcd];
yield ["-$b", "-$a", $gcd];
}
}

/**
* @dataProvider providerAbs
*
Expand Down

0 comments on commit 4f4b953

Please sign in to comment.