PHP » Quellcode betrachten

Download

<?php
/* fractions class
 * (C) 2006 Julian von Mendel (http://derjulian.net)
 * License: LGPL
 */

class DivisionByZeroException extends Exception{}
class 
ParametersException     extends Exception{}

class 
fraction
{
    public    
$numerator   0;
    public    
$denumerator 1;

    function 
__construct($denumerator=False,$numerator=1,$number=0)
    {
        if (!
$denumerator) return True;
        if (
is_string($denumerator)) return $this->setstring($denumerator);
        if (
is_float($denumerator) || is_int($denumerator)) return $this->setdecimal($denumerator);
        return 
$this->set($denumerator,$numerator,$number);
    }

    
    public function 
set($denumerator,$numerator=1,$number=0)
    { 
/* imports a fraction */

        
if (is_array($denumerator))
            list(
$denumerator,$numerator,$number) = $denumerator;

        
$denumerator = (int)$denumerator;
        
$numerator   = (int)$numerator  ;
        
$number      = (int)$number     ;
        if (
$denumerator == 0)
            throw new 
DivisionByZeroException("Denumerator can't be zero.");

        
$this->numerator   $numerator+$number*$denumerator;
        
$this->denumerator $denumerator                   ;
    }

    public function 
setdecimal($number)
    { 
/* imports a decimal fraction */

        
$number      = (float)$number;
        
$seperated   explode(".",(string)$number);
        if (!isset(
$seperated[1])) $seperated[1] = 0;
        
$numerator   $seperated[1];
        
$denumerator pow(10,strlen($seperated[1]));
        
$number      $seperated[0];

        return 
$this->set($denumerator,$numerator,$number);
    }

    public function 
setstring($string)
    { 
/* imports a string */

        
if (substr_count($string," ") == 1)
        {
            
$number  explode(" ",$string );
            
$string  $number[1]           ;
            
$number  = (int)trim($number[0]);
        }
        else
            
$number  0                    ;

        
$fraction    explode("/",$string );
        
$denumerator trim($fraction[1]   );
        
$numerator   trim($fraction[0]   );

        return 
$this->set($denumerator,$numerator,$number);
    }

    public function 
cancel()
    { 
/* cancels the fraction */

        
$gcd                math::greatestcommondivisor
        
(
            
$this->numerator,
            
$this->denumerator
        
);
        
$this->numerator   /= $gcd;
        
$this->denumerator /= $gcd;

        if (
$this->denumerator 0)
        {
            
$this->numerator  *= -1;
            
$this->denumerator abs($this->denumerator);
        }

        return 
True;
    }

    public static function 
commondenumerator($fractions)
    { 
/* calculates a new common denumerator for the given fractions */

        
if (!is_array($fractions)) throw new WrongParametersException("First parameter has to be an array!");
        
$values = array();
        foreach(
$fractions as &$fraction)
        {
            
// check wether fraction is an object or a decimal number
            
if (!is_object($fraction))
            { 
// if it is a object, convert it to a decimal number
                
$tmp       $fraction;
                
$fraction = new self();
                
$fraction->setdecimal($tmp);
                if (!
$fraction) throw new WrongParametersException("Fraction isn't a fraction object nor a valid decimal number!");
            }
            
$fraction_ $fraction->get();
            
$values[]  = $fraction_["denumerator"];
        }

        
$denumerator  math::leastcommonmultiple($values);

        foreach(
$fractions as &$fraction)
            
$fraction->multipleto($denumerator);

        return 
$fractions;
    }

    public function 
multipleby($n)
    { 
/* multiples the fraction with the given number */

        
$this->denumerator *= (int)$n;
        
$this->  numerator *= (int)$n;
        return 
True;
    }

    public function 
multipleto($n)
    { 
/* multiples the fraction with the given number */

        
if ($n $this->denumerator != 0) throw new WrongParametersException("The current denumerator MOD the new denumerator must be zero!");
        
$this->multipleby($n $this->denumerator);
        return 
True;
    }

    public static function 
calculate($fractions,$code_numerator,$code_denumerator=True,$first=False)
    { 
/* works through all $fractions, where every item in the array can be a
       * fraction object or a decimal number, and uses the given $code on them
       */

        
if (!is_array($fractions)) throw new WrongParametersException("First parameter has to be an array!");
        if (
$code_denumerator===True$code_denumerator $code_numerator;
        foreach(
$fractions as $fraction)
        {
            
// check wether fraction is an object or a decimal number
            
if (!is_object($fraction))
            { 
// if it is a object, convert it to a decimal number
                
$tmp       $fraction;
                
$fraction = new self();
                
$fraction->setdecimal($tmp);
                if (!
$fraction) throw new WrongParametersException("Fraction isn't a fraction object nor a valid decimal number!");
            }

            
// check wether this is the first round
            
if (!isset($denumerator))
            { 
// if yes, use the values of the first fraction as initial numbers
                
extract($fraction->get());
                if (!
$first) continue;
            }
            
// use the given code to calculate the new fraction
            
$tmp                     $fraction->get();
            
$current                 $tmp["denumerator"];
            
$new                     $denumerator;
            eval(
$code_denumerator);
            
$denumerator             $new;
            
$current                 $tmp["numerator"];
            
$new                     $numerator;
            eval(
$code_numerator);
            
$numerator               $new;
        }

        return new 
self($denumerator,$numerator);
    }

    public static function 
reciprocal($fractions)
    { 
/* switches numerator and denumerator*/

        
return self::calculate
        
(
            
$fractions                       ,
            
"$new = $tmp[\"denumerator\"];",
            
"$new = $tmp[\"numerator\"];"  ,
            
True
        
);
    }

    public static function 
addition($fractions)
    { 
/* adds together the given fractions */

        
$fractions self::commondenumerator($fractions);
        return 
self::calculate($fractions,"$new += $current;","");
    }

    public static function 
substraction($fractions)
    { 
/* substracts the given fractions */

        
$fractions self::commondenumerator($fractions);
        return 
self::calculate($fractions,"$new -= $current;","");
    }

    public static function 
multiplication($fractions)
    { 
/* multiplicates the given fractions */

        
return self::calculate($fractions,"$new *= $current;");
    }

    public static function 
division($fractions)
    { 
/* divides the given fractions */

        
return self::calculate($fractions,"$new *= $tmp[\"denumerator\"];","$new *= $tmp[\"numerator\"];");
    }

    public function 
getstring($format="%n %f",$fraction_format="%n / %d")
    { 
/* export fraction as string
    public function getstring($format="%n %f",$fraction_format="%n / %d",$html=False)
    { /* export fraction as string
       * -------------------------
       * $format:          you can use the placeholder "%n" which stands for the
       *                   integer in a mixed fraction. "%f" stands for the
       *                   fraction itself. if you don't want a mixed fraction,
       *                   set $format to "%f".
       * $fraction_format: placeholder "%n" is replaced by the numerator, "d" by
       *                   the denumerator.
       */

        // mixed or non-mixed fraction?
        
extract($this->get(substr_count($format,"%n") >= 1));

        
// detect algebraic sign
        
if ($number == 0$number    abs($number   );
        if (
$number <  0$numerator abs($numerator);

        
// replace placeholders
        
$fraction_format str_replace("%n",$numerator      ,$fraction_format);
        
$fraction_format str_replace("%d",$denumerator    ,$fraction_format);
        
$format          str_replace("%n",$number         ,$format         );
        
$format          str_replace("%f",$fraction_format,$format         );

        return 
$format;
    }

    public function 
__toString()
    { 
/* if object is exported as string, return the decimal fraction with two decimals */

        
return number_format($this->getdecimal(),2);
    }

    public function 
get($mixed=False)
    { 
/* export fraction as array; $mixed specifies if the fraction should be
       * mixed
       */

        
if ($mixed)
        { 
// mixed fraction
            
if ($this->numerator $this->denumerator 0)
                
$number      ceil($this->numerator $this->denumerator);
            else
                
$number      floor($this->numerator $this->denumerator);
            
$numerator   $this->numerator $this->denumerator;
            
$denumerator $this->denumerator;
        }
        else
        { 
// non-mixed fraction
            
$number      0;
            
$numerator   $this->numerator;
            
$denumerator $this->denumerator;
        }

        return array
        (
            
"denumerator" => $denumerator,
            
"numerator"   => $numerator,
            
"number"      => $number
        
);
    }

    public function 
getdecimal($decimals=2)
    { 
/* export fraction as decimal fraction */

        
$number $this->numerator $this->denumerator;
        return 
round($number,$decimals);
    }
}
?>

© 2009 Julian von Mendel (http://derjulian.net) | Datum: 27.05.2022