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); } } ?>