Home » Php » php – Look for the GCD (greatest common divisor) of more than 2 integers?

# php – Look for the GCD (greatest common divisor) of more than 2 integers?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I already have a function that finds the GCD of 2 numbers.

``````function getGCDBetween(\$a, \$b)
{
while (\$b != 0)
{
\$m = \$a % \$b;
\$a = \$b;
\$b = \$m;
}
return \$a;
}
``````

But now, I would like to extend this function to find the GCD of N points. Any suggestion ?

How to&Answers:

There is a more elegant way to do this :

``````// Recursive function to compute gcd (euclidian method)
function gcd (\$a, \$b) {
return \$b ? gcd(\$b, \$a % \$b) : \$a;
}
// Then reduce any list of integer
echo array_reduce(array(42, 56, 28), 'gcd'); // === 14
``````

If you want to work with floating points, use approximation :

``````function fgcd (\$a, \$b) {
return \$b > .01 ? fgcd(\$b, fmod(\$a, \$b)) : \$a; // using fmod
}
echo array_reduce(array(2.468, 3.7, 6.1699), 'fgcd'); // ~= 1.232
``````

You can use a closure in PHP 5.3 :

``````\$gcd = function (\$a, \$b) use (&\$gcd) { return \$b ? \$gcd(\$b, \$a % \$b) : \$a; };
``````

### Answer：

Had to do a bit of digging, but this is what I found.

The gcd of three numbers can be computed as gcd(a, b, c) = gcd(gcd(a,
b), c), or in some different way by applying commutativity and
associativity. This can be extended to any number of numbers.

You could use something like the following:

``````function multiGCD(\$nums)
{
\$gcd = getGCDBetween(\$nums[0], \$nums[1]);

for (\$i = 2; \$i < count(\$nums); \$i++) { \$gcd = getGCDBetween(\$gcd, \$nums[\$i]); }

return \$gcd;
}
``````

### Answer：

Take the GCD of numbers 1 and 2, and then the GCD of that and number 3, and so on.

### Answer：

You can try

``````function gcd(\$a, \$b) {
if (\$a == 0 || \$b == 0)
return abs(max(abs(\$a), abs(\$b)));
\$r = \$a % \$b;
return (\$r != 0) ? gcd(\$b, \$r) : abs(\$b);
}

function gcd_array(\$array, \$a = 0) {
\$b = array_pop(\$array);
return (\$b === null) ? (int) \$a : gcd_array(\$array, gcd(\$a, \$b));
}

echo gcd_array(array(50, 100, 150, 200, 400, 800, 1000)); // output 50
``````

### Answer：

I found a solution but it looks a bit ugly :

1) checking for every divisor of each integer

2) find the greater integer in every arrays

``````function getAllDivisorsOf(\$n)
{
\$sqrt = sqrt(\$n);
\$divisors = array (1, \$n);
for (\$i = 2; (\$i < \$sqrt); \$i++)
{
if ((\$n % \$i) == 0)
{
\$divisors[] = \$i;
\$divisors[] = (\$n / \$i);
}
}
if ((\$i * \$i) == \$n)
{
\$divisors[] = \$i;
}
sort(\$divisors);
return \$divisors;
}

function getGCDFromNumberSet(array \$nArray)
{
\$allDivisors = array ();
foreach (\$nArray as \$n)
{
\$allDivisors[] = getAllDivisorsOf(\$n);
}
\$allValues = array_unique(call_user_func_array('array_merge', \$allDivisors));
array_unshift(\$allDivisors, \$allValues);
\$commons = call_user_func_array('array_intersect', \$allDivisors);
sort(\$commons);
return end(\$commons);
}

echo getGCDFromNumberSet(array(50, 100, 150, 200, 400, 800, 1000)); // 50
``````

Any better idea ?

### Answer：

You can also use the gmp library:

``````<?php
\$gcd = gmp_gcd( '12', '21' );
echo gmp_strval( \$gcd );
?>
``````

### Answer：

You can store the numbers in an array and/or database and read from there. And then within a loop you can modular divide the array elements.

### Answer：

I found this somewhere calculates gcd by recursion

``````function gcd(...\$numbers) {
if (count(\$numbers) > 2) {
return array_reduce(\$numbers, 'gcd'); // use php's array reduce
}

\$r = \$numbers[0] % \$numbers[1];
return \$r === 0 ? abs(\$numbers[1]) : gcd(\$numbers[1], \$r);
}
``````