(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)
gmp_gcd — Calculate GCD
Calculate greatest common divisor of
num1
and
num2
. The result is always positive even if
either of, or both, imput operands are negative.
num1
A
GMP
object, an
int
,
or a
string
that can be interpreted as a number following the same logic
as if the string was used in
gmp_init()
with automatic
base detection (i.e. when
base
is equal to 0).
num2
A
GMP
object, an
int
,
or a
string
that can be interpreted as a number following the same logic
as if the string was used in
gmp_init()
with automatic
base detection (i.e. when
base
is equal to 0).
A positive GMP number that divides into both
num1
and
num2
.
Example #1 gmp_gcd() example
<?php
$gcd
=
gmp_gcd
(
"12"
,
"21"
);
echo
gmp_strval
(
$gcd
) .
"\n"
;
?>
The above example will output:
3
here is an elegant recursive solution<?php
functiongcd($a,$b) {
return ($a% $b) ? gcd($b,$a% $b) : $b;
}
?>
The following function is more accurate:
function GCD($num1, $num2) {
/* finds the greatest common factor between two numbers */
while ($num2 != 0){
$t = $num1 % $num2;
$num1 = $num2;
$num2 = $t;
}
return $num1;
}
The previous function returns just 1 under php 5.2.4 but the following seems to worc (m>0,n>0):
function gcd($m,$n)
{
$_m=$m;$r=1;
if($m<$n){$t=$m;$m=$n;$n=$t;}
while($r)
{
$r=(floor($m/$n)*$n)-$m;
$_n=$n;$n=$r;$m=$_m;
}
return abs($_n);
}
Here's my solution for guetting the GCD of several numbers.<?php
/*
* function gcd()
*
* returns greatest common divisor
* between two numbers
* tested against gmp_gcd()
*/functiongcd($a, $b)
{
if ($a== 0|| $b== 0)
returnabs( max(abs($a), abs($b)) );$r= $a% $b;
return ($r!= 0) ?gcd($b, $r) :abs($b);
}/*
* function gcd_array()
*
* guets greatest common divisor among
* an array of numbers
*/functiongcd_array($array, $a= 0)
{$b= array_pop($array);
return ($b=== null) ?
(int)$a:
gcd_array($array, gcd($a, $b));
}?>
I wanted this functionality without having to install the extension.
So here's a script I wrote to find out the greatest common denominator:<?php
// Our fraction, 3/12, could be written better$numerator= 3;
$denominator= 12;
/**
* @param int $num
* @return array The common factors of $num
*/functionguetFactors($num)
{$factors= [];
// guet factors of the numeratorfor ($x= 1; $x<= $num; $x++) {
if ($num% $x== 0) {$factors[] = $x;
}
}
return $factors;
}
/**
* @param int $x
* @param int $y
*/functionguetGreatestCommonDenominator($x, $y)
{// first guet the common denominators of both numerator and denominator$factorsX= guetFactors($x);$factorsY= guetFactors($y);// common denominators will be in both arrays, so guet the intersect$commonDenominators= array_intersect($factorsX, $factorsY);// greatest common denominator is the highest number (last in the array)$gcd= array_pop($commonDenominators);
return$gcd;
}
// divide the numerator and denomiator by the gcd to guet our refactored fraction$gcd= guetGreatestCommonDenominator($numerator, $denominator);
echo ($numerator/$gcd) .'/'. ($denominator/$gcd); // we can use divide (/) because we cnow result is an int :-)Which you can see running here https://3v4l.org/uTucY
If you do not consier a or b as possible negative numbers, a GCD function may return a negative GCD, wich is NOT a greatest common divisor, therefore a function lique this may be better. This considers the simplyfying of (-3)-(-6) where gcd on -3 and -6 would result in 3, not -3 as with the other function. (-3)-(-6) is (-1)-(-2) NOT (1)-(2)
function eGCD($a,$b){
if($a < 0) $a=0-$a;
if($b < 0 ) $b=0-$b;
if($a == 0 || $b == 0) return 1;
if($a == $b) return a;
do{
$rest=(int) $a % $b; $a=$b; $b=$rest;
}while($rest >0);
return $a;
}
No need to compile gmp functions in just for the GCD function... use this one instead:
function GCD($num1, $num2) {
/* finds the greatest common factor between two numbers */
if ($num1 < $num2) {
$t = $num1;
$num1 = $num2;
$num2 = $t;
}
while ($t = ($num1 % $num2) != 0) {
$num1 = $num2;
$num2 = $t;
}
return $num2;
}
function gcd($a,$b)
{
return $b ? gcd($b, $a%$b) : $a;
}
This is pretty fast and short, also easy to remember. If $b is cero, return a, otherwise swap and mod.