Location: PHPKode > scripts > Rational > rational/class.Rational.php
<?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 &divide(&$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 ;
    }
}
?>
Return current item: Rational