Pascallsches Dreieck in PHP programmiert, kleiner FEHLER

  • Hallo Leute,

    vor nen paar Tagenmeinte ich zu meiner Mathelehrerin ich würd noch ein Referat über das pascallsche Dreieck halten, so mit allem möglichem drum und dran, und so, dass die Mitschüler selbst ausprobieren können was für Muster dran kommen usw.. Hat alles funkltioniert, das Dreieck ist dynamisch aufgebaut (mit PHP ohne Db). Ausrechnen tut er mir auch alles bis ins unermessliche, kein Thema, aber sobald ich Durch x Teilbare Zahlen markieren lassen möchte macht er Probleme. Bis in die 30igste Reihe funktioniert alles wunderbar(oder n paar mehr). Anschließend setzen markierte Felder aus. betrachtet man es sich genau entsteht eine Parabel. Die aufm Kopf steht O.o ... Man sieht es aber nur wenn man die Einstellung auf Minimal stellt. Sja am besten mal selbst anschauen: http://pascal.topfkuchration.de . Wisst ihr woran das liegen könnte? Evtl. Serverleistung? Aber ausrechnen tut ers ja, und während es ausgerechnet wird, wird auch überprüft ob Farbig oder nicht ...

    Naja, guckt mal falls interessiert.

    Mfg, Felix.


    Quellcode(Kompletter Inhalt in dieser Datei!):

  • Das Problem liegt daran, dass die Zahlen zu groß für php sind. Bereits in der 35. Zeile überschreiten die Werte von "$zahl[$reihe][$platz]" die Zahl 2147483647. Dies ist der größte Integerwert.
    Man müsste nur noch herausfinden wie man mit noch größeren Werten rechnen kann.

    PS: Als Codeänderung (für meine Verhältnisse eindeutiger zu verstehen) in der 105. und 148. Zeile:

    Code
    $color = ($c != "" AND $zahl[$reihe][$platz]%$c == 0) ? "red" : "white";

    Sollte eigentlich genauso funktionieren (Wenn nicht gar noch besser, weil die Zehlen nicht dividiert werden müssen)(Ist aber trotzdem noch nicht die gesamte Lösung, da bei einigen Zahlen trotzdem noch modulo rumzickt).

    PSS: Ich werde mal schauen, ob nicht doch irgendwie größere Zahlen zu verarbeiten gehen.

    [EDIT]
    Da und da sind jeweils noch ein paar Beiträge, zu einer Ähnlichen Problematik (Modulo lässt sich halt nur auf Integers anwenden und dieser reicht leider nicht aus).

    [EDIT]
    http://de3.php.net/manual/de/ref.gmp.php Dies ist eine externe LIB, mit der man große Integers berechnen kann. Damit sollte es eigentlich funktionieren. Vielleicht ist bei deinem Hoster ja bereits diese LIB installiert.

    Viel Glück, Boman.

    Es gibt zwei Regeln fuer Erfolg im Leben:
    1. Erzaehle den Leuten nie alles, was Du weisst ...

  • Code
    $color = ($c != "" AND $zahl[$reihe][$platz]%$c == 0) ? "red" : "white";


    Die Art kenne ich gar nicht ...


    das mit der Library könnte funktionieren, aber leider ist die nicht installiert.. Kann man die installieren lassen/selbst installieren? Bin bei strato.de


    Edit: mti den den 2 anderen Links komm ich nich klar, wüsste nicht in welcher art ich das übernehmen könnte..

  • Code
    $color = ($c != "" AND $zahl[$reihe][$platz]%$c == 0) ? "red" : "white";


    Das ist eine Art, um einer Variablen einen Wert in abhängigkeit eines boolean zuweisen zu können.

    Code
    ($boolean) ? $wert_1 : wert_2;


    Der Rückgabewert dieser Zeile ist, wenn ($boolean == true) $wert_1 und bei ($boolean == false) $wert_2.
    Demzufolge wird bei ($c == "") direkt "white" zurückgegeben, denn dann ergibt der boolean immer false, egal welchen wert der Rest hinter AND auch annehmen würde.
    Bei ($c != "") steht es offen, was zurückgegeben wird, es hängt halt von ($zahl[$reihe][$platz]%$c == 0) ab und jenachdem, ob es true oder false ist wird "red" oder auch wieder "white" zurückgegeben.
    Das % in $zahl[$reihe][$platz]%$c == 0 ist Modulo, also der Rest, der Ganzzahligen Division der beiden Zahlen. Und wenn der Rest 0 ist, dann ist $c ein Teiler von $zahl[$reihe][$platz].

    Wegen der Klasse habe ich auch noch nichts weiteres Herausgefunden. Du kannst ja bei strato ja einmal anfragen ob die Klasse installiert werden kann.

    Die beiden anderen Links sind nicht so wichtig.

    Es gibt zwei Regeln fuer Erfolg im Leben:
    1. Erzaehle den Leuten nie alles, was Du weisst ...

  • int() funktioniert ja nur bis zu einer speziellen zahl. kann man nicht anhand des restes (%) überprüfen ob die rechnung aufgegangen ist? wir rbauchen ja keine ergebnisse, sondern nur "rot" oder "weiß" als ergebniss. (Frage führt auf ausgängliche Problematik zurück.)


    Edit: Das ist durch den von dir geschreibenen Code ja schon geschehen, funktioniert aber leider immer noch nich :/

  • Das Problem ist, dass wenn die Zahl größer als der spezielle Wert ist, dann wird sie nicht mehr als Integer gespeichert, sondern als Float.
    Das Problem an dem Daten-Typ Float ist, dass er die Zahl nicht genau abspeichert, sondern nur ungefähr: 2357745285661 wird beispielsweise zu 2357745285660. Mit diesen Zahlen lassen sich dann natürlich keine fehlerlosen Modulo-berechnungen durchführen, weil ja die letzte Zahl nicht übereinstimmt.
    Eine Möglichkeit, die Zahlen in voller 'Auflösung' zu speichern und auszuwerten wäre der Daten-Typ String. Allerdings fehlt hierzu der benötigte Modulo-Operator, um zwie Zeichenketten zu 'dividieren'. Dies so eine Funktion könnte man aber auch selber schreiben. Ich hab dafür gerade aber keinen Nerv :roll: . Vielleicht mag es auch noch andere Lösungsvarianten geben, aber diese sollte funktionieren.

    Es gibt zwei Regeln fuer Erfolg im Leben:
    1. Erzaehle den Leuten nie alles, was Du weisst ...

  • Spontan denk ich mal, dass es mit einer Array-Lösung zu machen wäre, aber das würde den ganzen code nur verkomplizieren.

  • Habe mich jetzt doch mal hin gesetzt, weil ich grad mal Lust hatte. Und folgendes kam dabei raus:


    Die Funktion summe bildet die summe von 2 Strings und liefert sie als String zurück.
    Die Funktion modulo errechnet den Rest der Division, der Zahl $string_1 durch $string_2. Und sie liefert das Ergebnis ebenfalls als String zurück. Allerdings ist noch ein Problem bei dieser Funktion vorhanden (welches für die Anwendung in deinem Fall nicht stört): Der Wert $string_2 darf nicht höher als 2147483647 sein.

    Was du jetzt noch machen musst ist, dass du die Werte der einzelnen Felder immer mit summe() zusammenrechnest und als String abspeicherts und dann per modulo()-Funktion vergleichst.
    Falls du die Zahlen, welche ja nun als Daten-Typ String vorliegen, doch noch als double brauchst (was eigentlich Schwachsinn wäre weil dies ungenauer ist) kannst du folgende Zeilen benutzen:

    Code
    $zahl_als_double = $zahl[$reihe][$platz];
    settype($zahl_als_double,"double"); //Jetzt ist $zahl_als_double der Double-Wert von $zahl[$reihe][$platz]

    Es gibt zwei Regeln fuer Erfolg im Leben:
    1. Erzaehle den Leuten nie alles, was Du weisst ...