<?php
//
// Edit History:
//
// $Author: dickmunroe $
// $Date: 2007/05/28 13:02:08 $
//
// Dick Munroe (hide@address.com) 04-Feb-2006
// Initial version created.
//
// Dick Munroe (hide@address.com) 28-May-2007
// Some versions of php don't lower case class names.
//
include_once 'Numerical/class.Numerical.php' ;
/**
* @author Dick Munroe <hide@address.com>
* @copyright copyright @ 2006-2007 by Dick Munroe, Cottage Software Works, Inc.
* @license http://www.csworks.com/publications/ModifiedNetBSD.html
* @version 1.0.1
* @package Rational
* @example ./example.php
*/
class Rational
{
var $n ;
var $d ;
/**
* Constructor for the Rational class.
*
* @access public
* @param mixed Numerator if a numerator/denominator pair is provided or
* an integer or a floating point number.
* @param integer [optional] Denominator of a rational number.
* @return void
*/
function Rational($n, $d = NULL)
{
if ($d !== NULL)
{
$this->n = $n ;
$this->d = $d ;
}
else if (strtolower(get_class($n)) == 'rational')
{
$this->n = $n->n ;
$this->d = $n->d ;
}
else if (is_numeric($n) && ($n == floor($n)))
{
$this->n = $n ;
$this->d = 1 ;
}
else if (is_float($n))
{
$xxx = Numerical::rational($n) ;
$this->n = $xxx[0] ;
$this->d = $xxx[1] ;
}
}
/**
* Add two rational numbers. May be called as a function or a method.
*
* @access public
* @param object Rational number to be added.
* @param object [optional] Second rational number to be added if the function form is used.
* @return reference to Rational.
*/
function &add(&$r, $r1 = NULL)
{
if ($r1 !== NULL)
{
$xxx = new Rational($r) ;
return $xxx->add($r1) ;
}
else
{
if ($this->d != $r->d)
{
$n = ($this->n * $r->d) + ($r->n * $this->d) ;
$d = ($this->d * $r->d) ;
}
else
{
$n = $this->n + $r->n ;
$d = $this->d ;
}
$this->n = $n ;
$this->d = $d ;
return $this->simplify() ;
}
}
/**
* Divide two rational numbers. May be called as a function or a method.
*
* @access public
* @param object Rational number to be divided by.
* @param object [optional] Second rational number to be divided into the first if the function form is used.
* @return reference to Rational.
*/
function ÷(&$r, $r1 = NULL)
{
if ($r1 !== NULL)
{
$xxx = new Rational($r) ;
return $xxx->divide($r1) ;
}
else
{
$xxx = new Rational($r->d, $r->n) ;
return $this->multiply($xxx) ;
}
}
/**
* Multiply two rational numbers. May be called as a function or a method.
*
* @access public
* @param object Rational number to be mutplied by.
* @param object [optional] Second rational number to be multiplied the first if the function form is used.
* @return reference to Rational.
*/
function &multiply(&$r, $r1 = NULL)
{
if ($r1 !== NULL)
{
$xxx = new Rational($r) ;
return $xxx->multiply($r1) ;
}
else
{
$n = $this->n * $r->n ;
$d = $this->d * $r->d ;
$this->n = $n ;
$this->d = $d ;
return $this->simplify() ;
}
}
/**
* Subtract two rational numbers. May be called as a function or a method.
*
* @access public
* @param object Rational number to be subtracted.
* @param object [optional] Second rational number to be subtracted if the function form is used.
* @return reference to Rational.
*/
function &subtract(&$r, $r1 = NULL)
{
if ($r1 !== NULL)
{
$xxx = new Rational($r) ;
return $xxx->subtract($r1) ;
}
else
{
if ($this->d != $r->d)
{
$n = ($this->n * $r->d) - ($r->n * $this->d) ;
$d = ($this->d * $r->d) ;
}
else
{
$n = $this->n - $r->n ;
$d = $this->d ;
}
$this->n = $n ;
$this->d = $d ;
return $this->simplify() ;
}
}
/**
* Convert the rational number to simplest form.
*
* @access public
* @return reference to rational number.
*/
function &simplify()
{
if ($this->n < $this->d)
{
$theFactors = Numerical::factor($this->n) ;
}
else
{
$theFactors = Numerical::factor($this->d) ;
}
foreach ($theFactors as $aFactor => $theCount)
{
if ($aFactor != 1)
{
do
{
if (($this->n % $aFactor == 0) && ($this->d % $aFactor == 0))
{
$this->n = $this->n/$aFactor ;
$this->d = $this->d/$aFactor ;
}
else
{
break ;
}
} while (true) ;
}
}
return $this ;
}
}
?>