User Tools

Site Tools


fractional_arithmetic

Back to: Arbitrary-Precision Math

Fractional Arithmetic in Arbitrary-Precision



Starting with arbitrary-precision integer fractions (A/B) and (C/D), we perform the desired arithmetic operation which results in integer fraction (E/F).

The four basic fractional arithmetic operations are shown below. Here we are dealing with integer values, but the mathematical relationships between the variables still holds universally for both integers and non-integer fraction values.


Add


Addition example:

A/B + C/D = 2126048046/1246561379 + 1543736255/376873333
=
E/F = 2725612808059252963/469795741692806207



/*
   ========================================================================
   This PHP function performs arbitrary-precision
   integer fraction addition without reduction.

   (A/B) + (C/D) = E/F
   
   ARGUMENTS:
   $A_B = First argument as string "A/B"
   $C_D = Second argument as string "C/D"
   
   OUTPUT:
   $E_F = Raw, unreduced fraction as string "E/F"
   
   ERRORS:
   No error checking is done.
   ========================================================================
*/

   function bcAdd_Frac ($A_B, $C_D)
{
   list($A,$B) = preg_split("[\/]", preg_replace("/\s+/", '', trim($A_B)));
   list($C,$D) = preg_split("[\/]", preg_replace("/\s+/", '', trim($C_D)));

   $E = bcadd(bcmul($A,$D), bcmul($B,$C));
   $F = bcmul($B,$D);

   return "$E/$F";
}

Subtract


Subtraction example:

A/B - C/D = 457317137/1768889034 - 950244052/540289318
=
E/F = -1433792719147083202/955711849797538812


/*
   ========================================================================
   This PHP function performs arbitrary-precision
   integer fraction subtraction without reduction.

   (A/B) - (C/D) = E/F
   
   ARGUMENTS:
   $A_B = First argument as string "A/B"
   $C_D = Second argument as string "C/D"
   
   OUTPUT:
   $E_F = Raw, unreduced fraction as string "E/F"
   
   ERRORS:
   No error checking is done.
   ========================================================================
*/

   function bcSub_Frac ($A_B, $C_D)
{
   list($A,$B) = preg_split("[\/]", preg_replace("/\s+/", '', trim($A_B)));
   list($C,$D) = preg_split("[\/]", preg_replace("/\s+/", '', trim($C_D)));

   $E = bcsub(bcmul($A,$D), bcmul($B,$C));
   $F = bcmul($B,$D);

   return "$E/$F";
}

Multiply


Multiplication example:

(A/B) * (C/D) = (1202898282/196311836) * (1572962581/1200002060)
=
E/F = 1892113986335185842/235574607602382160

/*
   ========================================================================
   This PHP function performs arbitrary-precision
   integer fraction multiplication without reduction.

   (A/B) * (C/D) = E/F

   ARGUMENTS:
   $A_B = First argument as string "A/B"
   $C_D = Second argument as string "C/D"
      
   OUTPUT:
   $E_F = Raw, unreduced fraction as string "E/F"
   
   ERRORS:
   No error checking is done.
   ========================================================================
*/

   function bcMul_Frac ($A_B, $C_D)
{
   list($A,$B) = preg_split("[\/]", preg_replace("/\s+/", '', trim($A_B)));
   list($C,$D) = preg_split("[\/]", preg_replace("/\s+/", '', trim($C_D)));

   $E = bcmul($A,$C);     $F = bcmul($B,$D);

   return "$E/$F";
}

Divide


Division example:

(A/B) / (C/D) = (256107163/2079436173) / (1073511327/1868176954)
=
E/F = 478453499670921502/2232298285489031571

/*
   ========================================================================
   This function performs arbitrary-precision
   integer fraction division without reduction.

   (A/B) / (C/D) = (E/F)
   
   ARGUMENTS:
   $A_B = First argument as string "A/B"
   $C_D = Second argument as string "C/D"
   
   OUTPUT:
   $E_F = Raw, unreduced fraction as string "E/F"
   
   ERRORS:
   No error checking is done.   
   ========================================================================
*/

   function bcDiv_Frac ($A_B, $C_D)
{
   list($A,$B) = preg_split("[\/]", preg_replace("/\s+/", '', trim($A_B)));
   list($C,$D) = preg_split("[\/]", preg_replace("/\s+/", '', trim($C_D)));

   $E = bcmul($A,$D);     $F = bcmul($B,$C);

   return "$E/$F";
}




Reduction To Lowest Terms

Given the returned output of any of the above functions, (E/F), we can compute the greatest common integer divisor (GCD) of both (E) and (F) and reduce (E/F) to its lowest terms (G/H), if possible. If (G/H) comes out identical to (E/F), the fraction is already in its lowest terms and cannot be reduced any further.









Notice that they all share

Below is a function that takes the integer fraction (E/F) and reduces it to lowest terms as integer fraction (G/H) via the GCD.

/*
   ========================================================================
   This function reduces arbitrary-precision integer fraction (E/F)
   to its lowest terms (G/H), if possible.

   Argument must be an integer fraction string in "E/F" format.

   ERRORS:
   No special error checking is done.
   ========================================================================
*/

   function bcReduce_Frac ($E_F)
{

// -----------------------------------------------
// Extract the individual fraction elements (E, F)
// from the input argument string ("E/F").

   list($E,$F) = preg_split("[\/]", str_replace(" ", "", trim($E_F)));

// -------------------------------------------------
// To find the GCD, we work with the absolute values
// of E and F, calling those working values wE and
// wF respectively.

   $wE = bcmul(((bccomp($E, 0) < 0)? -1:1), $E);
   $wF = bcmul(((bccomp($F, 0) < 0)? -1:1), $F);

   if (bccomp($wE,$wF) > 0) {$w=$wE;   $wE=$wF;   $wF=$w;}

// -------------------------------------
// Equate 1st approximation of GCD to wE

   $GCD = $wE;

// ------------------------------------------------
// Perform Euclid's algorithm loop while (wF != 0).
// The value of wF decreases after each cycle and
// eventually reaches zero, at which point we have
// reached the GCD value.

   while (bccomp($wF, 0) != 0)
         {
          $w=$wF;     $wF=bcmod($GCD, $wF);     $GCD=$w;
         }

// ------------------------------------------
// Compute and return reduced fraction (G/H).
// If GCD == 1, then the fraction cannot be
// reduced and is returned unchanged.

   $G = bcdiv($E, $GCD);
   $H = bcdiv($F, $GCD);

   return "$G/$H";
}
fractional_arithmetic.txt · Last modified: 2014/04/21 22:58 by Jay.Tanner.x@PHPScienceLabs.us