PHP » Mit Brüchen rechnen

Die math- und die fraction-Klasse laufen nur in Kombination. Die math-Klasse kann den größten gemeinsamen Teiler sowie das kleinste gemeinsame Vielfache beliebig vieler Werte über den euklidischen Algorithmus berechnen sowie Grad- und Bogenmaß ineinander umrechnen. Die fraction-Klasse kann beliebig viele Brüche importieren, exportieren, addieren, subtrahieren, multiplizieren, teilen, umkehren, kürzen und auf den gleichen Nenner bringen.

PHP bietet bereits nativ Funktionen an, die Grad- und Bogenmaß ineinander umrechnen: rad2deg() und deg2rad(). Die math-Klasse hat dann nur einen Vorteil, wenn man einen nicht-dezimal-Bruch als Ergebnis möchte (wie wir es in der Mathe-Hausaufgabe gebraucht haben…).

math-Klasse

<?php
error_reporting
(E_ALL);
require(
"math.php");
try
{
    echo 
"ggT von 3528 und 3780: ".math::greatestcommondivisor(3528,3780)."\n"// 252
    
echo "kgV von 3528 und 3780: ".math::leastcommonmultiple(3528,3780)."\n"// 52920
    
echo "ggT von 22, 6 und 12: ".math::greatestcommondivisor(array(22,6,12))."\n"// 2
    
echo "kgV von 22, 6 und 12: ".math::leastcommonmultiple(array(22,6,12))."\n"// 132
    
echo "Bogenmaß von 90°: ".math::degree2radian(90,False)."\n"// 0.5
    
echo "Gradmaß von 0.5: ".math::radian2degree(0.5)."\n"// 90"
}
catch(
Exception $e)
{
    echo 
"Error: ".$e->getMessage();
}
?>

fraction-Klasse

Import

Zuerst muss mit der fraction-Klasse ein Bruch importiert werden, der bearbeitet werden kann. Dazu gibt es die Funktionen set(), setdecimal() und setstring(). set() bekommt den Nenner, den Zähler und die Ganzzahl (standardmäßig 0) als Parameter übergeben. setdecimal() bekommt einen Dezimalbruch übergeben. setstring() einen String der Form "2 1/2", "2 1 / 2", "5/2", oder "5 / 2".

<?php
    $f 
= new fraction();
    
$f->set(2,1,2); // Der erste Parameter ist der Nenner!

    
$f = new fraction(2,1,2); // Statt set() aufzurufen kann man die Parameter auch direkt dem Konstruktor übergeben

    
$f = new fraction();
    
$f->setdecimal(2.5);

    
$f = new fraction(2.5); // Statt setdecimal() aufzurufen kann man die Dezimalzahl auch direkt dem Konstruktor übergeben

    
$f = new fraction();
    
$f->setstring("2 1 / 2");

    
$f = new fraction("5/2"); // Statt setstring() aufzurufen kann man den String auch direkt dem Konstruktor übergeben
?>

Export

Der Bruch kann als Array, Dezimalzahl oder String exportiert werden:

$mixed stellt ein, ob der Bruch mit Ganzzahl oder ohne exportiert werden soll. D. h. ob ein Array mit den Werten 2, 1 und 2 oder mit 5 und 4 exportiert werden soll, wenn der Bruch 2.5 importiert wurde.

getstring bekommt am besten als ersten Parameter "%f" oder "%n %f". "%f" würde den Bruch ohne Ganzzahl exportieren, "%n %f" mit, da "%n" durch die Ganzzahl ersetzt wird und "%f" durch Zähler und Nenner. Die Formatierung von Zähler und Nenner wird durch den zweiten Parameter bestimmt. Beim zweiten Parameter steht "%n" für den numerator (= Zähler) und "%d" für den denumerator (= Nenner). An dieser Einstellung muss im Normalfall nichts geändert werden.

Berechnungen

Die wichtigste Berechnung ist sicher das Kürzen. Das funktioniert so:

<?php
$f
->cancel();
?>

Um den Bruch zu erweitern gibt es die Funktionen multipleby() und multipleto(). multipleto() versucht dabei, den Nenner auf den übergebenen Parameter zu erweitern. Sollte das unmöglich sein, weil der übergebene Parameter geteilt durch den Nenner keine gerade Zahl ergibt, wird eine Exception ausgelöst.

<?php
$f
->multipleby(2); // 5/4 würde auf 10/8 erweitert werden
$f->multipleto(16); // 5/4 würde auf 20/16 erweitert werden
?>

Die im Folgenden genannten Funktionen bekommen jeweils ein Array mit beliebig vielen fraction-Objekten oder Dezimalzahlen übergeben.
commondenumerator() erweitert alle übergebenen Brüche auf den gleichen Nenner. reciprocal() invertiert alle übergebenen Brüche, d. h. aus 3/4 wird z. B. 4/3. Diese beiden Funktionen geben jeweils ein Array mit den erzeugten Ausgabebrüchen als fraction-Objekt zurück.

<?php
$f1 
= new fraction(0.75);
$f2 = new fraction(0.5);
$f3 3.0;

list(
$f1,$f2,$f3) = fraction::commondenumerator(array($f1,$f2,$f3));
$f2->getstring(); // 0 2 / 4
$f3->getstring(); // 3 0 / 4

list($f1,$f2,$f3) = fraction::reciprocal(array($f1,$f2,$f3));
$f1->getstring(); // 0 4 / 3
?>

addition(), substraction(), multiplication() und division() führen die Rechenoperationen aus, die sie bezeichnen und geben exakt ein fraction-Objekt zurück, welches das Ergebnis der Berechung enthält.

<?php
$f1 
= new fraction(2.5);
$f2 = new fraction(0.5);
$f3 3.0;

$addition fraction::addition(array($f1,$f2,$f3)); // 6
echo $addition->getdecimal()."\n";

$substraction fraction::substraction(array($f1,$f2,$f3)); // -1
echo $substraction->getdecimal()."\n";

$multiplication fraction::multiplication(array($f1,$f2,$f3)); // 3.75
echo $multiplication->getdecimal()."\n";

$division fraction::divison(array($f1,$f2,$f3)); // 1.66
echo $division->getdecimal()."\n";
?>

Eigene Berechnungen implementieren

Möchte man eigene Berechnungen auf mehrere Brüche anwenden, kann man evtl. die Funktion calculate() zu Hilfe nehmen. Dieser übergibt man ein Array mit fraction-Objekten bzw. Dezimalzahlen und zwei PHP-Code-Stücke, die auf den Zähler und den Nenner angewendet werden sollen. Weiterhin übergibt man ihr als 4. Paremter $first, welcher spezifiziert, ob die Code-Stücke auch auf das erste Element im Array angewendet werden. Bei einer Addition z. B. möchte man das erste Element nicht auf sich selbst addieren, d. h. man setzt $first = False. Bei der reciprocal-Funktion wird hingegen jedes Element invertiert, auch das erste. Dort muss $first = True gesetzt werden. Im folgenden zeige ich die Implementation der addition()-Funktion:

<?php
public static function addition($fractions)
{
    
$fractions self::commondenumerator($fractions);
    return 
self::calculate($fractions,"$new += $current;","",False);
}
?>

Die Funktion erweitert erst alle Brüche auf den gleichen Nenner. Als Code-Stück für die Verarbeitung des Zählers übergibt sie einen Programmabschnitt, der zu $new (welches der momentane Wert des Zählers ist) $current (welcher der Wert des Zählers des momentanen Elements ist) addiert. Am Nenner muss bei der Addition nichts geändert werden, deswegen steht für den dritten Parameter nur "" da. Um statt per $current auf den aktuellen Wert zuzugreifen kann man auch per $tmp["numerator"] und $tmp["denumerator"] auf den jeweils anderen Wert zugreifen.

math.php
Quellcode anzeigen | Herunterladen
fraction.php
Quellcode anzeigen | Herunterladen

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