volker: parseInt - Bug oder Mißverständnis

Hallo,

vielleicht kennt ja jemand schon das Problem ... im Forumsarchiv hab' ich jedenfalls nichts dazu gefunden.

Die Funktion parseInt() wandelt(parst) laut SelfHTML-Doku Zeichenketten in Ganzzahlen um.

Warum liefern die Aufrufe parseInt("09") und parseInt("08") eine 0, aber alle anderen Aufrufe, z.B. parseInt("07") korrekte Werte (7 in dem Fall)????

Vielen Dank schon mal...

Volker

  1. Hallo Volker

    Warum liefern die Aufrufe parseInt("09") und parseInt("08") eine 0, aber alle anderen Aufrufe, z.B. parseInt("07") korrekte Werte (7 in dem Fall)????

    Hab's ausprobiert und kann Deine Probleme bestaetigen. Aber woran es liegt, kann ich auch nicht erklaeren. Folgende Funktion hatte ich zum Testen:

    <script language="JavaScript">
    Liste = new Array("01","02","03","04","05","06","07","08","09");
    for(i=0;i<9;i++)
    {
      x = parseInt(Liste[i]);
      document.write(x + "<br>");
    }
    </script>

    bis 7 klappt es, dann folgen zwiei 0er. Mit MSIE und Netscape.

    Mit eval(...) anstelle parseInt(...) hab ich es dann zwar geschafft, aber das Raetsel ist dadurch natuerlich nicht geloest.

    viele Gruesse
      Stefan Muenz

    1. Hallo Volker, Hallo Stefan

      Warum liefern die Aufrufe parseInt("09") und parseInt("08") eine 0, aber alle anderen Aufrufe, z.B. parseInt("07") korrekte Werte (7 in dem Fall)????

      Des Raetsels Loesung fuer dieses, in unseren Augen etwas unnatuerliche, Verhalten liegt im Ursprung der Sprache JavaScript. Die Sprache JavaScript kommt aus dem Umfeld von UNIX und C. Die normale Zahlendarstellung, die man unter UNIX haufig findet ist aber das oktale Zahlensystem (d1 = o1; d2 = o2; ... ; d8 = o10) unter in diesem Zahlensystem gibt es dann natuerlich die Ziffern 8 und 9 nicht und damit arbeitet dann ausgerechnet parseInt.
      Loesung fuer das ganze ist ein doch etwas spaerlich dokumentierter Parameter der Funktion parseInt, der das Zahlensystem festlegt. Am besten sollte man also parseInt( Number, Base) als Prototyp verwenden.

      Michael N.

      PS: Auch ich bin in diese Falle schonmal gestolpert und es hat mich einiges an Zeit gekostet diesen Parameter zu entdecken.

      1. Hallo Michael,

        danke fuer die Aurklaerung!

        Ich hatte zwar auch schon an was Oktales gedacht, aber ich konnte es nicht recht glauben. Wirklich ne fiese Falle!

        viele Gruesse
          Stefan Muenz

        1. Hallo Michael,

          danke fuer die Aurklaerung!

          Ich hatte zwar auch schon an was Oktales gedacht, aber ich konnte es nicht recht glauben. Wirklich ne fiese Falle!

          viele Gruesse
            Stefan Muenz

          Hallo Stefan,

          die Falle ist noch 'ne Spur fieser:
          Uebergibt man parseInt() Werte mit fuehrender Null, so interpretiert er sie oktal, ohne die fuehrende Null wird alles automatisch dezimal interpretiert, das steht aber dann nirgendwo mehr, das erfaehrt man nur durch ausprobieren.

          Und noch ein Nachtrag: den Parameter "Base" habe ich im "JavaScript Guide" zum Netscape Navigator Version 4.0 unter parseInt() als optionalen Parameter "radix" gefunden, diese Sonderfunktionalitaet der Zeichenkette, um die sich dieser Thread dreht ist aber nicht dokumentiert.

          Aber es gibt noch mehr solche "Scherze". Wenn man z.B. in einer Zeichenkette eine Zahl hat, dann kann man nachdem man sie extrahiert hat (ueber split()), davon zwar ohne Probleme subrahieren, eine Addition ist aber nicht so ohne weiteres moeglich.

          Beispiel:

          function demo()
          {
            var Datum     = "1998-12-31";
            var arrDatum = Datum.split("-");
            var Jahr        = arrDatum[0];
            var Monat     = arrDatum[1];
            var Tag         = arrDatum[2];

          var BspJahrEins = Jahr - 1;
            var BspJahrZwei = Jahr + 1;
            var BspJahrDrei = Jahr - 1 + 2;

          var AusgDatum = BspJahrEins + "-" + Monat + "-" + Tag;
            alert(AusgDatum);

          var AusgDatum = BspJahrZwei + "-" + Monat + "-" + Tag;
            alert(AusgDatum);

          var AusgDatum = BspJahrDrei + "-" + Monat + "-" + Tag;
            alert(AusgDatum);
          }

          Beim ersten alert erhaelt man dann ausgegeben: "1997-12-31";
          Beim zweiten alert erhaelt man dann ausgegeben: "19981-12-31"
          Und beim dritten alert erhaelt man dann ausgegeben: "1999-12-31"

          Verrueckt oder?

          Bis dann

          Michael N.

          1. Hallo,

            Ich hatte zwar auch schon an was Oktales gedacht, aber ich konnte es nicht recht glauben. Wirklich ne fiese Falle!

            Bisschen hinterhaeltig, die Syntax, ja.

            die Falle ist noch 'ne Spur fieser:
            Uebergibt man parseInt() Werte mit fuehrender Null, so interpretiert er sie oktal, ohne die fuehrende Null wird alles automatisch dezimal interpretiert,

            Stimmt fast, hexadezimal gibt es auch noch (wie das geht, kommt hier gleich noch).

            das steht aber dann nirgendwo mehr, das erfaehrt man nur durch ausprobieren.
            Und noch ein Nachtrag: den Parameter "Base" habe ich im "JavaScript Guide" zum Netscape Navigator Version 4.0 unter parseInt() als optionalen Parameter "radix" gefunden, diese Sonderfunktionalitaet der Zeichenkette, um die sich dieser Thread dreht ist aber nicht dokumentiert.

            Doch, steht tatsaechlich beschrieben - "Client-Side JavaScript Reference" :
            "if the radix is not specified or is specified as 0, JavaScript assumes the following:
                 If the input string begins with "0x", the radix is 16 (hexadecimal).
                 If the input string begins with "0", the radix is eight (octal).
                 If the input string begins with any other value, the radix is 10 (decimal).
              If the first character cannot be converted to a number, parseInt returns NaN."

            ----------------------

            Aber es gibt noch mehr solche "Scherze". Wenn man z.B. in einer Zeichenkette eine Zahl hat, dann kann man nachdem man sie extrahiert hat (ueber split()), davon zwar ohne Probleme subrahieren, eine Addition ist aber nicht so ohne weiteres moeglich.

            (ich habe beim Zitieren mal ein bisschen umsortiert wegen der Anschaulichkeit)

            var Datum     = "1998-12-31";
              var arrDatum = Datum.split("-");
              var Jahr        = arrDatum[0];

            »»   ...

            (1) var BspJahrZwei = Jahr + 1;
              (2) var BspJahrEins = Jahr - 1;
              (3) var BspJahrDrei = Jahr - 1 + 2;

            var AusgDatum = BspJahrZwei + "-" + Monat + "-" + Tag;
              ...ausgegeben: "19981-12-31"
             var AusgDatum = BspJahrEins + "-" + Monat + "-" + Tag;

            »»   ... ausgegeben: "1997-12-31";

            var AusgDatum = BspJahrDrei + "-" + Monat + "-" + Tag;
              ...ausgegeben: "1999-12-31"

            Verrueckt oder?

            Verblueffend. Schon.
            Verrueckt? Weniger.
            Was passiert hier?
            JavaScript kennt keine Typfestlegung von Variablen per Deklaration.
            Typ wird aus dem Kontext heraus waehrend der Ausfuehrung festgelegt.

            Im Beispiel ist Jahr  vom Typ string, der Wert ist "1998".
            (1) Operator "+" verknuepft Strings
                 "1998" + "1"  = "19981"  
            (2) Operator "-" kann keine Strings verknuepfen, den gibt es naemlich dafuer nicht, also
                 wird "1998" zu integer 1998 konvertiert
                 1998 - 1 = 1997
            (3) 1998 - 1 = 1997     /   1997 + 2 = 1999   (Operationen von links nach rechts)

            Die Zuweisung zu AusgDatum ist in allen drei Faellen wieder  Verknuepfung von Strings durch "+". Und damit sind die Ergebnisse alle nachvollziehbar, oder?

            Gruss
            Christine

            1. Hallo Christine,

              Und damit sind die Ergebnisse alle nachvollziehbar, oder?

              Ja, und ich sehe an diesen schoenen Erklaerungen von dir auch mal, wie wichtig es ist, mal die genauen Ablaeufe in so einer Programmiersprache ohne explizite Variablentypen genauer zu verdeutlichen. Betrachte ich als wichtigen Input fuer meine D... (na, du weisst schon;-)

              viele Gruesse
                Stefan Muenz