probleme in php beim wurzelziehen
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
ausgeben
aussage
befehl
beschreibung
button
code
dank
endergebnis
ergebnis
falsche eingabe
hilfe
http
neun
null
programm
quellcode
url
wurzel
zahl
ziehen
-
Ich brauche Hilfe bei einem PHP Programm, das ich geschrieben habe.
das Programm ist hier:
http://andreu.lima-city.de/pjrost/wurzel.php
der Quellcode ist hier:
http://andreu.lima-city.de/pjrost/wurzel.phps
Ich soll die Wurzel einer beliebigen Zahl z ziehen und mit einer Genauigkeit von 10e-9 ausgeben.
Bei Quadratzahlen soll das Ergebnis ohne Nachkommastellen ausgegeben werden. Es wird verglichen ob das Ergebnis mal sich selber die Zahl z ergibt.
Die Wurzel bekomme ich duch Näherung heraus (Iteratives Wurzelziehen nach Lisa, Beschreibung im Quelltext) womit beim quadrieren des Ergebnisses dieses etwas von der Zahl z abweicht (außer bei Quadratzahlen).
Nun hab ich das Problem, dass bei manchen Quadratzahlen das Ergebnis mit 9 Nachkommastellen ausgegeben wird und bei anderen nicht. So ist die Wurzel aus 9 gleich 3 aber die Wurzel aus 16 gleich 4.000000000.
Meine Frage ist jetzt ob man diesen Fehler beheben kann, und wenn ja wie.
Ich bedanke mich jetzt schon für eure Hilfe. (:
MfG andreu
Endergebnis:
Danke für die Hilfe darkpandemic, dank dir konnte ich meinen Code fehlerfrei gestalten. Hier mein neuer Code:
$str_w = number_format($w, 9); $new_w = rtrim(rtrim($str_w, "0"), "."); $temp = $new_w."000000"; $temp2 = number_format($w, 15); if($temp == $temp2){ echo $str_w;} else{echo $new_w;}
Update Endergebnis:
Der Endgültige Code (hoffe ich):
$str_w = number_format($w, 9); $new_w = rtrim(rtrim($str_w, "0"), "."); $temp = number_format($w, 10); $temp = rtrim(rtrim($temp, "0"), if($new_w == $temp){ echo $new_w;} else{echo $str_w;}
Beitrag zuletzt geändert: 17.4.2011 16:42:09 von andreu -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Um die nachkommastelle los zu werden brauchst du nur
die Funktion intval() benutzen.
http://de3.php.net/manual/de/function.intval.php
-
Das Programm soll ja auch die Wurzel aus Nicht-Quadratzahlen berechnnen und ausgeben und diese Ergebnisse haben Nachkommastellen.
Wenn du dir den Quelltext angeschaut hast, solltest du gesehen haben, dass ich es mit if( ($w * $w) == $z ) versucht habe, aber dieser Befehl wird anscheinend übersprungen oder so...
Beitrag zuletzt geändert: 16.4.2011 22:01:08 von andreu -
Hallo andreu,
probiere mal Folgendes:
if( $w - intval($w) < 10e-9) { echo intval($w); } else { printf("%.9f", $w); }
-
Hallo darkpandemic,
danke für deinen Beitrag (:
Die Wurzel aus 16 ist jetzt wieder 4 und nicht mehr 4.000000000 xD
ich denk mal mit dieser Syntax klappt es für alle Zahlen größer 1, aber wie siehts aus mit Zahlen kleiner 1 ??
zB wird die Wurzel aus 0.25 als 0.500000000 ausgegeben.
Sie wurde mit der anderen Syntax auch mit 9 Nachkommastellen ausgegeben...
Beitrag zuletzt geändert: 16.4.2011 22:17:44 von andreu -
Hallo andreu,
ich dachte, Du brauchst das nur für Ganzzahlen.
Also probieren wir jetzt mal folgendes:
if( abs($w*$w-$z) < 10e-9) { echo $w; } else { printf("%.9f", $w); }
Edit:
Ich habe noch eine einfachere Methode gefunden:
$str_w = number_format($w, 9); $str_w = rtrim(rtrim($str_w, "0"), "."); echo $str_w;
Edit 2:
Habe gerade gemerkt, das ist auch nicht gut. Die 9. Nachkommastelle kann ja eine 0 sein.
Aber wenn Du es in den ersten if-Block schreibst, dann sollte es passen.
Beitrag zuletzt geändert: 16.4.2011 22:36:34 von darkpandemic -
Hallo darkpandemic,
nochmals danke für deinen Beitrag (:
das erste mit dem abs hat nicht so ganz geklappt... bei wurzel aus 0.01 hat er mir 0.100000000001 (was eigentlich nicht möglich sein sollte das es ja eigentlich auf 9 Nachkommastellen begrenzt ist... eigentlich...)
das zweite klappt da schon besser (:
Du meinst das eine irrationale Zahl bei der die 9. Nachkommastelle eine 0 ist diese verlieren könnte??
Ich glaub so kann man es verhindern:
$str_w = number_format($w, 9); $new_w = rtrim(rtrim($str_w, "0"), "."); $temp = number_format($w, 10); if($temp == $new_w){ echo $new_w;} else{echo $str_w;}
anstatt der 10 vllt ne größere Zahl falls die 10. Nachkommastelle auch ne Null sein sollte...
Update:
Ich glaub es ist eher:
if($temp == $new_w){ echo $str_w;} else{echo $new_w;}
xD
Update 2:
Ich seh grad es ist Falsch aber ich denk mal so in der Art lässt es sich machen....
Endergebnis:
Jetzt hab ich das hier und ich behaubte mal es ist Bombenfest xD
$str_w = number_format($w, 9); $new_w = rtrim(rtrim($str_w, "0"), "."); $temp = $new_w."000000"; $temp2 = number_format($w, 15); if($temp == $temp2){ echo $str_w;} else{echo $new_w;}
Beitrag zuletzt geändert: 16.4.2011 23:29:23 von andreu -
Hallo andreu,
Bombenfest ist es nicht. Die 16. oder ein weiter hinten liegende Nachkommastelle kann ja wieder ungliech Null sein.
Allerdings brauchst Du Dir wohl keine Sorgen zu machen, weil man das Problem eigentlich nicht wirklich Lösen kann.
Wenn die Wurzel mit einer Genauigkeit von 10^-9 bestimmt wird, dann schlägt der Fehler auf das Quadrat mit 10^-18 durch.
D.h. man müsste das Quadrat der Wurzel mit dem Ursprungswert mindestens bis zur 18. Nachkommastelle vergleichen.
Aber PHP hat nur ungefähr 14 Geltende Ziffern. Vielleicht kann man einen Trick finden um das zu verbessern aber irgendwann ist halt immer Schluss. Und es kann immer passieren, dass ein Unterschied erst jenseits der Rechengenauigkeit auftritt.
Von daher denke ich, dass man es mit normalen PHP-Floats nicht besser hinbekommt.
Falls Du doch an einer höheren Genauigkeit interessiert bist, dann kannst Du Dir ja mal Folgendes anschauen:
http://php.net/manual/en/book.bc.php
Da kannst Du dann z.B. mit
festlegen, dass auf 100 Nachkommastellen genau gerechnet werden soll. Das gilt aber nur für die bc*() Funktionen.bcscale(100);
Beitrag zuletzt geändert: 17.4.2011 0:12:18 von darkpandemic -
Öhm... Das sieht mir schwerer aus, als es sein sollte... Hier mal ein Vorschlag, passend zur Uhrzeit:
<?php $z = strip_tags($_POST['txtz']); ?> <html> <head> <title>Iteratives Wurzelziehen nach Lisa</title> </head> <body> <h1><u>Iteratives Wurzelziehen nach Lisa</u></h1> <form method="POST" action="<?php echo $_SERVER['PHP_SELF']?>"> Zahl eingeben, von der die Wurzel gezogen werden soll:<br> <input type="text" name="txtz" value="<?php echo $z?>"> <input type="submit" name="button" value="Wurzel ziehen."> </form> <hr> <?php if (isset($_POST['button'])) { if($z < 0 || $z == "" || $z < 10e-9) { echo '<script>alert("Falsche Eingabe.");</script><noscript>Falsche Eingabe</noscript>'; } else { $a = bcsqrt($z, 9); $b = (float)number_format($a).'.000000000'; if($a == $b) { $c = number_format($b); } else { $c = $a; } echo 'Die Wurzel aus '.$z.' ist '.$c; } } ?> </body> </html>
Wobei $b bzw. der Vergleich zwischen $a und $b sich noch einfacher und besser gestalten ließe.
Beitrag zuletzt geändert: 17.4.2011 0:41:21 von fabo -
Da kommt bei Wurzel aus 0 ein Dialogfenster: Falsche Eingabe.
Aber die Wurzel aus 0 ist möglich, sie ist 0. Denn 0² = 0*0 = 0 --> Wurzel aus 0 ist 0 -
deswegen würde ich auch nur prüfen, ob $z eine Zahl ist (mit is_numeric, um auch Zahlen mit Komma zu berücksichtigen):
<?php $z = strip_tags($_POST['txtz']); ?> <html> <head> <title>Iteratives Wurzelziehen nach Lisa</title> </head> <body> <h1><u>Iteratives Wurzelziehen nach Lisa</u></h1> <form method="POST" action="<?php echo $_SERVER['PHP_SELF']?>"> Zahl eingeben, von der die Wurzel gezogen werden soll:<br> <input type="text" name="txtz" value="<?php echo $z?>"> <input type="submit" name="button" value="Wurzel ziehen."> </form> <hr> <?php if (isset($_POST['button'])) { if(!is_numeric($z)) { echo '<script>alert("Falsche Eingabe.");</script><noscript>Falsche Eingabe</noscript>'; } else { $a = bcsqrt($z, 9); if($a-intval($a) < 10e-9) { $c = intval($a); } else { $c = $a; } echo 'Die Wurzel aus '.$z.' ist '.$c; } } ?> </body> </html>
Um das jetzt aber nochmal zu klären: Ganzzahlen sollen ohne, und alles Andere mit 9 Nachkommastellen angezeigt werden, oder?
Also sollen beispielsweise bei 0, 1, 4, 9, 16, usw... keine Nachkommastellen angezeigt werden, jedoch bei 2, 3, 5, usw...?
Du kannst theoretisch auch mit
prüfen, ob es sich um eine Quadratzahl handelt, oder nicht.sqrt($z) == ceil(sqrt($z))
Beitrag zuletzt geändert: 17.4.2011 1:07:42 von fabo -
Hallo fabo,
ich glaube, dass es darum geht die Wurzel gerade nicht mit einer vorgefertigten Funktion sondern mit dem iterativen Näherungsverfahren zu berechnen. Von daher scheidet bcsqrt() als Lösung aus.
Die neun Nachkommastellen sollen immer dann angegeben werden, wenn sich die Wurzel mit weniger als neun Stellen nicht darstellen läst.
Also:
4 -> 2
0.25 -> 0.5
2 -> 1.414213562
4.56 -> 2.13541565040
Und der letzte Fall gehört zu den Interessanten, da die Null am Ende bleiben soll. -
Hallo fabo,
ich schließe mich darkpandemeic an. Ich muss die Wurzel mit dem iterativen Näherungsverfahren lösen und deswegen scheiden die PHP internen Wurzelfunktionen aus.
Hallo groovestreet,
ich habe das Abfangen der Eingabe verändert. Jetzt funktioniert wieder die Wurzel aus 0.
Hallo darkpandemic,
ich habe den Code leicht verändert:
$str_w = number_format($w, 9); $new_w = rtrim(rtrim($str_w, "0"), "."); $temp = number_format($w, 10); $temp = rtrim(rtrim($str_w, "0"), "."); if($new_w == $temp){ echo $new_w;} else{echo $str_w;}
Ich schau nur noch ob die 10. Nachkommastelle 0 ist oder nicht. Wenn sie Null ist geh ich davon aus, dass nur noch Nuller kommen.
Ich hab das gleiche mit 20 Nachkommastellen probiert und das Ergebnis war, dass es kaum eine Zahl gibt die keine Nachkommstellen im Bereich von 10e-9 und 10e-20 hat.
Wer sich wundert, wieso die Wurzel aus 0 gleich 0.000000000 der soll wissen, dass die 10. Nachkommastelle eine 4 ist.
Im Quelltext steht auch ein echo der Zahl temp auskommentiert drin. Jeder hat die Chance meine Aussage nachzuvollziehen.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage