Slobodan: Perl: Zahlen runden auf x dez. Stellen

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

  1. 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

    1. 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

      1. 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

        1. Hallo Jörk,

          vielen Dank fuer Deine Aufklaerungsarbeit in Sachen RE! Damit stehe ich wirklich noch ziemlich auf Kriegsfuss ;-)

          viele Gruesse
            Stefan Muenz

          1. 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

    2. 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!