Math_Fraction
[ class tree: Math_Fraction ] [ index: Math_Fraction ] [ all elements ]

Source for file FractionOp.php

Documentation is available at FractionOp.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available through the world-wide-web at the following url:           |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Kouber Saparev <kouber@php.net>                             |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: FractionOp.php,v 1.4 2007/07/18 14:53:31 kouber Exp $
  20.  
  21. include_once 'Math/Fraction.php';
  22.  
  23. /**
  24.  * Math_FractionOp: static class to operate on Math_Fraction objects
  25.  *
  26.  * @author  Kouber Saparev <kouber@php.net>
  27.  * @version 0.4.1
  28.  * @access  public
  29.  * @package Math_Fraction
  30.  */
  31. class Math_FractionOp {
  32.  
  33.     /**
  34.      * Checks if a given object is an instance of PEAR::Math_Fraction
  35.      *
  36.      * @static
  37.      * @return boolean 
  38.      * @access public
  39.      */
  40.     function isFraction($n)
  41.     {
  42.         if (function_exists('is_a')) {
  43.             return is_a($n'math_fraction');
  44.         else {
  45.             return (strtolower(get_class($n)) == 'math_fraction' 
  46.                     || is_subclass_of($n'math_fraction'));
  47.         }
  48.     }
  49.  
  50.     /**
  51.      * Compares two fractions.
  52.      * if $n1 > $n2, returns 1,
  53.      * if $n1 == $n2, returns 0,
  54.      * if $n1 < $n2, returns -1
  55.      *
  56.      * @static
  57.      * @param object $n1 Math_Fraction
  58.      * @param object $n2 Math_Fraction
  59.      * @return int 
  60.      * @access public
  61.      */
  62.     function compare($n1$n2
  63.     {
  64.         if (!Math_FractionOp::isFraction($n1
  65.             || !Math_FractionOp::isFraction($n2)) {
  66.             return Math_FractionOp::raiseError('Both arguments must be PEAR::Math_Fraction objects');
  67.         else {
  68.             $num1 $n1->getNum();
  69.             $den1 $n1->getDen();
  70.  
  71.             $num2 $n2->getNum();
  72.             $den2 $n2->getDen();
  73.  
  74.             $lcm Math_FractionOp::lcm($den1$den2);
  75.  
  76.             $f1 $num1 $lcm/$den1;
  77.             $f2 $num2 $lcm/$den2;
  78.  
  79.             if ($f1 $f2{
  80.                 return -1;
  81.             else {
  82.                 return intval($f1 $f2);
  83.             }
  84.         }
  85.     }
  86.  
  87.     /**
  88.      * Returns the sum of two fractions: n = n1 + n2
  89.      *
  90.      * @static
  91.      * @param object $n1 Math_Fraction
  92.      * @param object $n2 Math_Fraction
  93.      * @return object Math_Fraction 
  94.      * @access public
  95.      */
  96.     function add($n1$n2$return_simplified = true
  97.     {
  98.         if (!Math_FractionOp::isFraction($n1
  99.             || !Math_FractionOp::isFraction($n2)) {
  100.             return Math_FractionOp::raiseError('Both arguments must be PEAR::Math_Fraction objects');
  101.         else {
  102.             $den1 $n1->getDen();
  103.             $den2 $n2->getDen();
  104.             $lcm Math_FractionOp::lcm($den1$den2);
  105.             $num $n1->getNum($lcm/$den1 $n2->getNum($lcm/$den2;
  106.             $f = new Math_Fraction(intval($num)$lcm);
  107.             if ($return_simplified{
  108.                 return Math_FractionOp::simplify($f);
  109.             else {
  110.                 return $f;
  111.             }
  112.         }
  113.     }
  114.  
  115.     /**
  116.      * Returns the subtraction of two fractions: n = n1 - n2
  117.      *
  118.      * @static
  119.      * @param object $n1 Math_Fraction
  120.      * @param object $n2 Math_Fraction
  121.      * @return object Math_Fraction 
  122.      * @access public
  123.      */
  124.     function sub($n1$n2$return_simplified = true
  125.     {
  126.         if (!Math_FractionOp::isFraction($n1
  127.             || !Math_FractionOp::isFraction($n2)) {
  128.             return Math_FractionOp::raiseError('Both arguments must be PEAR::Math_Fraction objects');
  129.         else {
  130.             return Math_FractionOp::add($n1new Math_Fraction($n2->getNum()*-1$n2->getDen())$return_simplified);
  131.         }
  132.     }
  133.  
  134.     /**
  135.      * Returns the product of two fractions: n = n1 * n2
  136.      *
  137.      * @static
  138.      * @param object $n1 Math_Fraction
  139.      * @param object $n2 Math_Fraction
  140.      * @return object Math_Fraction 
  141.      * @access public
  142.      */
  143.     function mult($n1$n2$return_simplified = true
  144.     {
  145.         if (!Math_FractionOp::isFraction($n1
  146.             || !Math_FractionOp::isFraction($n2)) {
  147.             return Math_FractionOp::raiseError('Both arguments must be PEAR::Math_Fraction objects');
  148.         else {
  149.             $num $n1->getNum($n2->getNum();
  150.             $den $n1->getDen($n2->getDen();
  151.             $f = new Math_Fraction(intval($num)$den);
  152.             if ($return_simplified{
  153.                 return Math_FractionOp::simplify($f);
  154.             else {
  155.                 return $f;
  156.             }
  157.         }
  158.     }
  159.  
  160.     /**
  161.      * Returns the quotient of two fractions: n = n1 / n2
  162.      *
  163.      * @static
  164.      * @param object $n1 Math_Fraction
  165.      * @param object $n2 Math_Fraction
  166.      * @return object Math_Fraction 
  167.      * @access public
  168.      */
  169.     function div($n1$n2$return_simplified = true
  170.     {
  171.         if (!Math_FractionOp::isFraction($n1
  172.             || !Math_FractionOp::isFraction($n2)) {
  173.             return Math_FractionOp::raiseError('Both arguments must be PEAR::Math_Fraction objects');
  174.         else {
  175.             return Math_FractionOp::mult($n1Math_FractionOp::reciprocal($n2)$return_simplified);
  176.         }
  177.     }
  178.  
  179.     /**
  180.      * Returns the greatest common divisor of two integers.
  181.      *
  182.      * @static
  183.      * @param int $n1 
  184.      * @param int $n2 
  185.      * @return int 
  186.      * @access public
  187.      */
  188.     function gcd($n1$n2
  189.     {
  190.         $n1 intval($n1);
  191.         $n2 intval($n2);
  192.  
  193.         $n1 abs($n1);
  194.         $n2 abs($n2);
  195.  
  196.         if ($n1 $n2{
  197.             $t $n1;
  198.             $n1 $n2;
  199.             $n2 $t;
  200.         }
  201.  
  202.         while ($n2 != 0){
  203.             $t $n1 $n2;
  204.             $n1 $n2;
  205.             $n2 $t;
  206.         }
  207.  
  208.         return intval($n1);
  209.     }
  210.  
  211.     /**
  212.      * Returns the least common multiple of two integers.
  213.      *
  214.      * @static
  215.      * @param int $n1 
  216.      * @param int $n2 
  217.      * @return int 
  218.      * @access public
  219.      */
  220.     function lcm($n1$n2)
  221.     {
  222.         $n1 intval($n1);
  223.         $n2 intval($n2);
  224.  
  225.         $n1 abs($n1);
  226.         $n2 abs($n2);
  227.  
  228.         return intval(($n1 $n2Math_FractionOp::gcd($n1$n2));
  229.     }
  230.  
  231.     /**
  232.      * Returns the reciprocal value of a fraction: n = 1/n
  233.      *
  234.      * @static
  235.      * @param object $n Math_Fraction
  236.      * @return object Math_Fraction 
  237.      * @access public
  238.      */
  239.     function reciprocal($n
  240.     {
  241.         if (!Math_FractionOp::isFraction($n)) {
  242.             return Math_FractionOp::raiseError('Argument must be PEAR::Math_Fraction object');
  243.         else {
  244.             $num $n->getNum();
  245.             $den $n->getDen();
  246.             return new Math_Fraction($den$num);
  247.         }
  248.     }
  249.  
  250.     /**
  251.      * Returns the simplified value (reduction) of a fraction.
  252.      *
  253.      * @static
  254.      * @param object $n Math_Fraction
  255.      * @return object Math_Fraction 
  256.      * @access public
  257.      */
  258.     function &simplify(&$n)
  259.     {
  260.         if (!Math_FractionOp::isFraction($n)) {
  261.             return Math_FractionOp::raiseError('Argument must be PEAR::Math_Fraction object');
  262.         else {
  263.             $num $n->getNum();
  264.             $den $n->getDen();
  265.             $gcd Math_FractionOp::gcd($num$den);
  266.             if ($gcd > 1{
  267.                 return new Math_Fraction($num/$gcd$den/$gcd);
  268.             else {
  269.                 return $n;
  270.             }
  271.         }
  272.     }
  273.  
  274.     /**
  275.      * An alias of the Math_FractionOp::simplify() method.
  276.      *
  277.      * @static
  278.      * @param object $n Math_Fraction
  279.      * @return object Math_Fraction 
  280.      * @access public
  281.      */
  282.     function &reduce(&$n)
  283.     {
  284.         return Math_FractionOp::simplify($n);
  285.     }
  286.  
  287.     /**
  288.      * Converts float to fraction and try to keep the maximal possible precision.
  289.      *
  290.      * @static
  291.      * @param float $f 
  292.      * @return object Math_Fraction 
  293.      * @access public
  294.      */
  295.     function floatToFraction($f)
  296.     {
  297.         $f floatval($f);
  298.  
  299.         // keep the original sign so that the numerator could be converted later
  300.         $is_negative ($f < 0);
  301.         if ($is_negative{
  302.             $f *= -1;
  303.         }
  304.  
  305.         // get the part before the floating point
  306.         $int floor($f);
  307.  
  308.         // make the float belonging to the interval [0, 1)
  309.         $flt $f $int;
  310.  
  311.         // strip the zero and the floating point
  312.         $flt substr($flt2);
  313.  
  314.         // try to get an integer for the numerator
  315.         do {
  316.             $len strlen($flt);
  317.             $val $int pow(10$len$flt;
  318.             $flt substr($flt0-1);
  319.         while ($val intval($val));
  320.  
  321.         if ($is_negative{
  322.             $val *= -1;
  323.         }
  324.  
  325.         $num intval($val);
  326.         $den pow(10$len);
  327.  
  328.         return new Math_Fraction($num$den);
  329.     }
  330.  
  331.     /**
  332.      * Converts string to fraction.
  333.      *
  334.      * @static
  335.      * @param string $str 
  336.      * @return object Math_Fraction 
  337.      * @access public
  338.      */
  339.     function stringToFraction($str)
  340.     {
  341.         if (preg_match('#^(-)? *?(\d+) *?/ *?(-)? *?(\d+)$#'trim($str)$m)) {
  342.             $num =$m[2];
  343.             $den =$m[4];
  344.  
  345.             if ($m[1xor $m[3]{
  346.                 // there is one "-" sign => the fraction is negative
  347.                 $num *= -1;
  348.             }
  349.  
  350.             if (!$den{
  351.                 return Math_FractionOp::raiseError('Denominator must not be zero.');
  352.             else {
  353.                 return new Math_Fraction($num$den);
  354.             }
  355.         else {
  356.             return Math_FractionOp::raiseError('Invalid fraction.');
  357.         }
  358.     }
  359.  
  360.     /**
  361.      * An error capturing function.
  362.      *
  363.      * @static
  364.      * @param string $str 
  365.      * @return object PEAR::raiseError() 
  366.      * @access public
  367.      */
  368.     function raiseError($str)
  369.     {
  370.         include_once 'PEAR.php';
  371.         return PEAR::raiseError($str);
  372.     }
  373. }
  374. ?>

Documentation generated on Mon, 11 Mar 2019 15:07:36 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.