Fractional Arithmetic Calculator
PHP Program by Jay Tanner
Integer Fraction (A / B)
A 
B 

Integer Fraction (C / D)
C 
D 

Double-Click Within Text Area to Select ALL Text

Basic Fractional Arithmetic

Below are PHP functions that were developed to perform signed arbitrary precision fractional arithmetic.  Here, arbitrary precision means to virtually any number of digits. 

In order to work with integer fractions, we need to establish the basic algebraic rules of fractional arithmetic.  These algebraic rules will still hold true even when the numeric values are non-integers, but here we are using only integers.


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 - 2024
   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