/*
###########################################################################
This function reduces an arbitrary-precision integer fraction (A/B) to its
lowest terms (a/b), if reduction is possible. If it cannot be reduced, then
the fraction comes back unchanged.
The argument can be any signed integer fraction string in 'A/B' format.
Values (A, B) are signed integers.
ERRORS:
FALSE is returned if either (A, B) argument is non-numeric.
NO DEPENDENCIES
###########################################################################
*/
function BC_Reduce_Frac ($A_B)
{
// Extract the individual fraction elements (A, B)
// from the input argument string ("A/B").
list($A,$B) = PReg_Split("[\/]", Str_Replace(' ','', trim($A_B)));
$A = trim($A); if (!Is_Numeric($A)) {return FALSE;}
$B = trim($B); if (!Is_Numeric($B)) {return FALSE;}
/* To find the GCD, we work with the absolute values
of E and F, calling those working values (wE) and
(wF) respectively.
*/
$wA = Str_Replace('-','', $A);
$wB = Str_Replace('-','', $B);
if (bcComp($wA,$wB) > 0) {$w=$wA; $wA=$wB; $wB=$w;}
// Equate 1st approximation of GCD to wA.
$GCD = $wA;
/* Perform Euclid's algorithm loop while (wB <> 0).
The value of wB decreases after each cycle and
eventually reaches zero, at which point we have
reached the GCD value. This will always equate
to at least 1.
*/
while (bcComp($wB,0) <> 0) {$w=$wB; $wB=bcMod($GCD,$wB); $GCD=$w;}
/* Compute and return numerator and denominator of reduced
integer fraction (a/b). When GCD == 1, it means that the
fraction could not be reduced and so, will be returned
unchanged.
*/
return bcDiv($A, $GCD).'/'.bcDiv($B, $GCD);
} // End of BC_Reduce_Frac (...)