razionale.php

<?php
/*
 * Copyright (C) 2003, 2004, 2005, 2006 Gionata Massi
 *
 * This file is part of Simplex-in-PHP.
 *
 *  Simplex-in-PHP is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Simplex-in-PHP is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Foobar; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
*/
class razionale {
    public 
$num;
    public 
$den;
    public function 
razionale($num 0$den 1) {
        
$this->num $num;
        
$this->den $den;
    }
    public function 
gcd($x$y) {
        
$a abs($x);
        
$b abs($y);
        if (
$b $a) {
            
$tmp $a;
            
$a $b;
            
$b $tmp;
        }
        for (;;) {
            if (
$b == 0) return $a;
            else if (
$b == 1) return $b;
            else {
                
$tmp $b;
                
$b $a $b;
                
$a $tmp;
            }
        }
    }
    public function 
normalize() {
        
$s $this->sign_int($this->den);
        if (
$s == 0printf("Zero denominator.");
        else if (
$s 0) {
            
$this->den = - $this->den;
            
$this->num = - $this->num;
        }
        
$g $this->gcd($this->num$this->den);
        if (
$g != 1) {
            
$this->num/= $g;
            
$this->den/= $g;
        }
        return 
$this;
    }
    public function 
sign_int($i) {
        if (
$i 0) return 1;
        if (
$i 0) return -1;
        return 
0;
    }
    public function 
sign() {
        if (
$this->num 0) return 1;
        if (
$this->num 0) return -1;
        return 
0;
    }
    public function 
addfrac($x$y) {
        
$somma = new razionale;
        if (!isset(
$x) || $x->num == 0) {
            
$this->num $y->num;
            
$this->den $y->den;
        } else if (!isset(
$y) || $y->num() == 0) {
            
$this->num $x->num;
            
$this->den $x->den;
        } else {
            
$somma->num $x->num $y->den $x->den $y->num;
            
$somma->den $x->den $y->den;
            
$somma->normalize();
            
$this->num $somma->num;
            
$this->den $somma->den;
        }
    }
    public function 
subfrac($x$y) {
        
$differenza = new razionale;
        if (!isset(
$x) || $x->num == 0) {
            
$this->num = - $y->num;
            
$this->den $y->den;
        } else if (!isset(
$y) || $y->num == 0) {
            
$this->num $x->num;
            
$this->den $x->den;
        } else {
            
$differenza->num $x->num $y->den $x->den $y->num;
            
$differenza->den $x->den $y->den;
            
$differenza->normalize();
            
$this->num $differenza->num;
            
$this->den $differenza->den;
        }
    }
    public function 
mulfrac($x$y) {
        
$prodotto = new razionale;
        if (!isset(
$x) || !isset($y) || $x->num == || $y->num == 0) {
            
$this->num 0;
            
$this->den 1;
        } else if (
$x->value() == 1) {
            
$this->num $y->num;
            
$this->den $y->den;
        } else if (
$y->value() == 1) {
            
$this->num $x->num;
            
$this->den $x->den;
        } else if (
$x->value() == - 1) {
            
$this->num = - $y->num;
            
$this->den $y->den;
        } else if (
$y->value() == - 1) {
            
$this->num = - $x->num;
            
$this->den $x->den;
        } else {
            
$prodotto->num $x->num $y->num;
            
$prodotto->den $x->den $y->den;
            
$prodotto->normalize();
            
$this->num $prodotto->num;
            
$this->den $prodotto->den;
        }
    }
    public function 
divfrac($x$y) {
        
$quoziente = new razionale;
        if (
$x->num == 0) {
            
$this->num 0;
            
$this->den 1;
        } else if (
$y->num == 0) {
            
printf("Division by zero");
        } else {
            
// echo "\n<br />divido " . $x->fractoa() . " per " . $y->fractoa();
            
$quoziente->num $x->num $y->den;
            
$quoziente->den $x->den $y->num;
            
$quoziente->normalize();
            
$this->num $quoziente->num;
            
$this->den $quoziente->den;
            
// echo " e ottengo " . $this->fractoa() . "<br />\n";
            
        
}
    }
    public function 
negatefrac() {
        
$this->num = - $this->num;
    }
    public function 
invertfrac() {
        
$tmp $this->num;
        
$this->num $this->den;
        
$this->den $tmp;
        
$s $this->sign_int($this->den);
        if (
$s == 0) exit(1);
        else if (
$s 0) {
            
$this->den = - $this->den;
            
$this->num = - $this->num;
        }
    }
    public function 
comparefrac($x$y) {
        
$this->subfrac($x$y);
        return 
$this->sign_int($this->num);
    }
    public function 
scanfrac($x) {
        
// Se c'e' uno slash e' espresso direttamente come frazione
        
if (strchr($x"/")) {
            
$num_den explode("/"$xstrlen($x));
            
$this->num $num_den[0];
            
$this->den $num_den[1];
        } else if (
strchr($x".")) { // e' espresso come decimale
            // facciamo fare il lavoro al PHP
            
$float $x;
            
settype($float"double");
            
// quante cifre dopo la virgola?
            
$decimali strlen(strchr($x".")) - 1;
            
$this->den pow(10$decimali);
            
$this->num $float $this->den;
        } else { 
// e' un intero
            
$this->num $x;
            
$this->den 1;
        }
    }
    public function 
fractoa() {
        if (
$this->den == 1$str sprintf("%d"$this->num);
        else 
$str sprintf("%d/%d"$this->num$this->den);
        return 
$str;
    }
    public function 
num() {
        return 
$this->num;
    }
    public function 
den() {
        return 
$this->den;
    }
    public function 
value() {
        return 
$this->num $this->den;
    }
    public function 
set($num$den) {
        
$this->num $num;
        
$this->den $den;
    }
}
?>