|
THE BASIC RULES OF FRACTIONAL ARITHMETIC
Given Two Integer Fractions (A/B) and (C/D) GCD = Greatest Common Divisor of Both Numerator and Denominator
<?php
/*
==================================================================
This PHP module contains functions to perform basic signed integer
fraction arithmetic using arbitrary-precision arithmetic.
Author : Jay Tanner - 2025
License : Public Domain
---------------------------
'A/B' , 'C/D' = Integer fractions as strings.
'E/F' = Returned fractional result as string.
ReduceFlag = FALSE = Return raw, non-reduced fraction. (default)
= TRUE = Return fraction reduced to lowest terms.
==================================================================
*/
/*
----------------------------------------------------------
This function adds two integer fractions with the option
to reduce the result to lowest terms.
(A/B) + (C/D) = (A*D + B*C) / (B*D) = E/F
Where:
E = A*D + B*C
and
F = B*D
NO DEPENDENCIES
ERRORS:
FALSE is returned if invalid integer fraction is detected.
----------------------------------------------------------
*/
function BC_Add_Frac ($A_Bstr, $C_Dstr, $ReduceFlag=FALSE)
{
$A_B = Str_Replace(' ', '', trim($A_Bstr));
$C_D = Str_Replace(' ', '', trim($C_Dstr));
if (Is_Numeric($A_B)) {$A_B = "$A_B/1";}
if (Is_Numeric($C_D)) {$C_D = "$C_D/1";}
list($A,$B) = PReg_Split("[\/]", $A_B);
list($C,$D) = PReg_Split("[\/]", $C_D);
if (
!Is_Numeric($A) or !Is_Numeric($B)
or !Is_Numeric($C) or !Is_Numeric($D)
)
{return FALSE;}
$E = bcAdd(bcMul($A,$D), bcMul($B,$C));
$F = bcMul($B,$D);
// If ReduceFlag === TRUE, then reduce to lowest terms.
// Otherwise return the raw, non-reduced value.
if ($ReduceFlag === TRUE)
{
$A = Str_Replace('-', '', Str_Replace('+', '', $E));
$B = Str_Replace('-', '', Str_Replace('+', '', $F));
if (bcComp($B,$A) < 0) {$w=$B; $B=$A; $GCD=$w;} else {$GCD=$A;}
while ($B <> 0) {$w=$B; $B=bcMod($GCD,$B); $GCD=$w;}
// Reduce E/F to lowest terms, if possible.
$E = bcDiv($E, $GCD);
$F = bcDiv($F, $GCD);
}
return "$E / $F";
}
/*
-------------------------------------------------------------
This function subtracts two integer fractions with the option
to reduce the result to lowest terms.
(A/B) - (C/D) = (A*D - B*C) / (B*D) = E/F
Where:
E = A*D - B*C
and
F = B*D
NO DEPENDENCIES
ERRORS:
FALSE is returned if invalid integer fraction is detected.
----------------------------------------------------------
*/
function BC_Sub_Frac ($A_Bstr, $C_Dstr, $ReduceFlag=FALSE)
{
$A_B = Str_Replace(' ', '', trim($A_Bstr));
$C_D = Str_Replace(' ', '', trim($C_Dstr));
if (Is_Numeric($A_B)) {$A_B = "$A_B/1";}
if (Is_Numeric($C_D)) {$C_D = "$C_D/1";}
list($A,$B) = PReg_Split("[\/]", $A_B);
list($C,$D) = PReg_Split("[\/]", $C_D);
if (
!Is_Numeric($A) or !Is_Numeric($B)
or !Is_Numeric($C) or !Is_Numeric($D)
)
{return FALSE;}
$E = bcSub(bcMul($A,$D), bcMul($B,$C));
$F = bcMul($B,$D);
// If ReduceFlag === TRUE, then reduce to lowest terms.
// Otherwise return the raw, non-reduced value.
if ($ReduceFlag === TRUE)
{
$A = Str_Replace('-', '', Str_Replace('+', '', $E));
$B = Str_Replace('-', '', Str_Replace('+', '', $F));
if (bcComp($B,$A) < 0) {$w=$B; $B=$A; $GCD=$w;} else {$GCD=$A;}
while ($B <> 0) {$w=$B; $B=bcMod($GCD,$B); $GCD=$w;}
// Reduce E/F to lowest
// terms, if possible.
$E = bcDiv($E, $GCD);
$F = bcDiv($F, $GCD);
}
return "$E / $F";
}
/*
----------------------------------------------------------
This function multiplies two integer fractions with the
option to reduce the result to lowest terms.
A/B * C/D = (A*C)/(B*D) = E/F
Where:
E = A*C
and
F = B*D
NO DEPENDENCIES
ERRORS:
FALSE is returned if invalid integer fraction is detected.
----------------------------------------------------------
*/
function BC_Mul_Frac ($A_Bstr, $C_Dstr, $ReduceFlag=FALSE)
{
$A_B = Str_Replace(' ', '', trim($A_Bstr));
$C_D = Str_Replace(' ', '', trim($C_Dstr));
if (Is_Numeric($A_B)) {$A_B = "$A_B/1";}
if (Is_Numeric($C_D)) {$C_D = "$C_D/1";}
list($A,$B) = PReg_Split("[\/]", $A_B);
list($C,$D) = PReg_Split("[\/]", $C_D);
if (
!Is_Numeric($A) or !Is_Numeric($B)
or !Is_Numeric($C) or !Is_Numeric($D)
)
{return FALSE;}
$E = bcMul($A,$C);
$F = bcMul($B,$D);
// If ReduceFlag === TRUE, then reduce to lowest terms.
// Otherwise return the raw, non-reduced value.
if ($ReduceFlag === TRUE)
{
$A = Str_Replace('-', '', Str_Replace('+', '', $E));
$B = Str_Replace('-', '', Str_Replace('+', '', $F));
if (bcComp($B,$A) < 0) {$w=$B; $B=$A; $GCD=$w;} else {$GCD=$A;}
while ($B <> 0) {$w=$B; $B=bcMod($GCD,$B); $GCD=$w;}
// Reduce E/F to lowest
// terms, if possible.
$E = bcDiv($E, $GCD);
$F = bcDiv($F, $GCD);
}
return "$E / $F";
}
/*
-----------------------------------------------------------
This function divides two integer fractions with the option
to reduce the result to lowest terms.
(A/B) / (C/D) = (A*D) / (B*C) = E/F
Where:
E = A*D
and
F = B*C
NO DEPENDENCIES
ERRORS:
FALSE is returned if invalid integer fraction is detected.
-----------------------------------------------------------
*/
function BC_Div_Frac ($A_Bstr, $C_Dstr, $ReduceFlag=FALSE)
{
$A_B = Str_Replace(' ', '', trim($A_Bstr));
$C_D = Str_Replace(' ', '', trim($C_Dstr));
if (Is_Numeric($A_B)) {$A_B = "$A_B/1";}
if (Is_Numeric($C_D)) {$C_D = "$C_D/1";}
list($A,$B) = PReg_Split("[\/]", $A_B);
list($C,$D) = PReg_Split("[\/]", $C_D);
if (
!Is_Numeric($A) or !Is_Numeric($B)
or !Is_Numeric($C) or !Is_Numeric($D)
)
{return FALSE;}
$E = bcMul($A,$D);
$F = bcMul($B,$C);
// If ReduceFlag === TRUE, then reduce to lowest terms.
// Otherwise return the raw, non-reduced value.
if ($ReduceFlag === TRUE)
{
$A = Str_Replace('-', '', Str_Replace('+', '', $E));
$B = Str_Replace('-', '', Str_Replace('+', '', $F));
if (bcComp($B,$A) < 0) {$w=$B; $B=$A; $GCD=$w;} else {$GCD=$A;}
while ($B <> 0) {$w=$B; $B=bcMod($GCD,$B); $GCD=$w;}
// Reduce E/F to lowest
// terms, if possible.
$E = bcDiv($E, $GCD);
$F = bcDiv($F, $GCD);
}
return "$E / $F";
}
?>
| ||||||
| Program by Jay Tanner Revised: Thursday, January 01, 1970 at 12:00:00 AM UTC | ||||||