Perl: Zahlen runden auf x dez. Stellen
Slobodan
Hi !
Hat jemand eine Idee wieso bei mir das runden in Perl nicht klappt.
-Versuch 1:
$gerundet = sprintf ("%0.2f",$wert);
Wenn das Ding "einfach" auf die Seite geschrieben wird klappt es.
Wenn ich das ganze in:
print " blablabla $gerundet\n";
reinsetze wird z.B das 6.55 als 6.00 dargestellt.
-Versuch 2:
$gerundet = int(($wert+.005)*100)/100
$gerundet in HTML reingesetzt liefert das gleiche.
Problem besteht auf dem Server in Win95- und auch in UNIX-Umgebung.
Was mache ich falsch ?
Slobodan
Hallo Slobodan,
-Versuch 1:
$gerundet = sprintf ("%0.2f",$wert);
Wenn das Ding "einfach" auf die Seite geschrieben wird klappt es.
Wenn ich das ganze in:
print " blablabla $gerundet\n";
reinsetze wird z.B das 6.55 als 6.00 dargestellt.
-Versuch 2:
$gerundet = int(($wert+.005)*100)/100
$gerundet in HTML reingesetzt liefert das gleiche.
Eine dritte Moeglichkeit stellen Regular Expressions dar. Da Perl jede Variable so behandelt, wie man es geade will, kann man auch Suche-Ersetze-Funktionen fuer Zeichenketten auf Zahlen loslassen. Aber: das folgende Beispiel packe ich auch nicht ganz. Ich bekomme immer entweder eine oder drei Nachkommastellen heraus, nie zwei (ich vermute aber eher mal, dass es an meinen Faehigkeiten liegt, RegExps perfekt einzusetzen). Hier das Prinzip:
print "Content-type: text/html\n\n";
print "<html><head></head><body>\n";
$test = 3 / 7;
$test =~ s/.(\d{2})*/.\1/g;
print "$test";
print "</body></html>\n";
Kannst dich ja mal selbst versuchen in dem Suche-Ersetze-Muster <g>
viele Gruesse
Stefan Muenz
Hallo Stefan!
Eine dritte Moeglichkeit stellen Regular Expressions dar. Da Perl jede Variable so behandelt, wie man es geade will, kann man auch Suche-Ersetze-Funktionen fuer Zeichenketten auf Zahlen loslassen. Aber: das folgende Beispiel packe ich auch nicht ganz. Ich bekomme immer entweder eine oder drei Nachkommastellen heraus, nie zwei (ich vermute aber eher mal, dass es an meinen Faehigkeiten liegt, RegExps perfekt einzusetzen). Hier das Prinzip:
print "Content-type: text/html\n\n";
print "<html><head></head><body>\n";$test = 3 / 7;
$test =~ s/.(\d{2})*/.\1/g;
print "$test";print "</body></html>\n";
Das mit den RegExps ist nicht immer ganz so einfach, wie man denkt... Ich mußte auch
erst freimal hinschauen, bevor ich überhaupt einen Fehler gesehen habe ;-)
In Deinem Beispiel bekommst Du in $test eine Zahl mit 15 Nachkommastellen. Die RE nun sucht
nach einem Punkt gefolgt von einer geraden Anzahl von Ziffern (also 14). Über die Klammern
werden die ersten beiden Ziffern "festgehalten" und anschließend über \1 wieder eingesetzt.
Die Option "g" zieht hier leider nicht, da sie nur die wiederholte Anwendung der RE auf den
original Text bewirkt - nicht jedoch auf einen manipulierten ... Mal abgesehen davon, daß Deine
RE keine Rundung durchführt, müßte sie in zwei Beziehungen verändert werden:
1. bei einer ungeraden Anzahl von Stellen, muß auch das letzte Zeichen mit entfernt werden
2. bei weniger als zwei Stellen sollten noch Nullen angehängt werden
Lösung könnte sein (es gibt ja immer viele Arten ein Problem zu lösen):
$test =~ s/.(\d{0,2})\d*/.$1/;
Um nur die ersten beiden Stellen auszugeben
$test =~ s/.(\d{0,2})\d*/substr(".${1}00",0,3)/e;
Um die Nachkommastellen mit Nullen aufzufüllen
$test =~ s/(.(\d{0,2})\d*)?$/substr(".${1}00",0,3)/e;
Um auch Zahlen ohne Komma mit zwei Nachkommastellen darzustellen
Hoffe das hilft vielleicht auch beim eigentlichen Problem weiter,
Gruß Jörk
So ein Ärger aber auch. Da ist mir jetzt glatt noch ein Fehler beim eintippen unterlaufen:
$test =~ s/.(\d{0,2})\d*/substr(".${1}00",0,3)/e;
Um die Nachkommastellen mit Nullen aufzufüllen$test =~ s/(.(\d{0,2})\d*)?$/substr(".${1}00",0,3)/e;
Um auch Zahlen ohne Komma mit zwei Nachkommastellen darzustellen
Die letzte Änderung bewirkt ja, daß ich nun zwei Klammer-Paare habe :(
Dabei fällt mir gerade auf, daß ich den Punkt ja auch generell in die innere Klammer
hereinnehmen kann :). Nun gut! die Lösung ist jetzt, entweder sich auf die zweite Klammer
zu beziehen, oder aber die erste Klammer keiner Variablen zuzuweisen; Dies geschiet durch
ein "?:" welches direkt der öffnenden Klammer folgt:
$test =~ s/(?:(.\d{0,2})\d*)?$/substr("${1}00",0,3)/e;
Jörk
Hallo Jörk,
vielen Dank fuer Deine Aufklaerungsarbeit in Sachen RE! Damit stehe ich wirklich noch ziemlich auf Kriegsfuss ;-)
viele Gruesse
Stefan Muenz
Hallo nochmal!
vielen Dank fuer Deine Aufklaerungsarbeit in Sachen RE! Damit stehe ich wirklich noch ziemlich auf Kriegsfuss ;-)
Ich muß gestehen, daß ich ganz gerne mit diesen Dingern rumspiele. Auch wenn nicht
alles auf Anhieb klappt. Aber wenn man mal ein bißchen dahinter gekommen ist
kann man damit schon einige Sachen auf den Kopf stellen (besonders die Personen, die
dann Versuchen, dahinterzukommen, was man damit sagen will) ;-)))
Gruß,
Jörk
hi!
Eine dritte Moeglichkeit stellen Regular Expressions dar. Da Perl jede Variable so
behandelt, wie man es geade will, kann man auch Suche-Ersetze-Funktionen fuer
Zeichenketten auf Zahlen loslassen.
print "Content-type: text/html\n\n";
print "<html><head></head><body>\n";$test = 3 / 7;
$test =~ s/.(\d{2})*/.\1/g;
Ich würde sagen: $test =~ s/.(\d{2})\d*/.\1/g;
print "$test";
print "</body></html>\n";
bye, Frank!