home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Math / FractionOp.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  10.7 KB  |  374 lines

  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($n1, new 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($n1, Math_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 * $n2) / Math_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($flt, 2);
  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($flt, 0, -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[1] xor $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. ?>