Mario: Array Fehler oder Endlosschleife

Hallo. Folgendes Skript macht mir Probleme:

Laenge = -1;
while((Laenge < 0) || (Laenge >= Banner.length))
{
Laenge = Banner.length;
Zufallszahl = Math.random()*Laenge;
Zufallszahl = Math.round(Zufallszahl);
}
document.write(Banner[Zufallszahl]);

Seit ich in der While Abfrage das >= eingebaut hab, baut der mir ne Endlosschleife, ich weiß aber nicht, warum. Schreib ich nur das > dann baut er mir alle paar Versuche ein "undefined" in die Seite ein anstelle des Banners. Ich geh mal davon aus, daß das Array an dieser Stelle nicht definiert ist, kann jedoch nicht ganz nachvollziehen, warum. Wie krieg ich das weg ???

  1. while((Laenge < 0) || (Laenge >= Banner.length))
    {
    Laenge = Banner.length;
    Zufallszahl = Math.random()*Laenge;
    Zufallszahl = Math.round(Zufallszahl);
    }

    Seit ich in der While Abfrage das >= eingebaut hab, baut der mir ne Endlosschleife, ich weiß aber nicht, warum.

    Deine while-Bedingung lautet:

    wenn [..] oder Laenge größer/GLEICH Banner.length

    Eine Zeile darunter setzt Du dann Laenge GLEICH Banner.length. Da ist es kein Wunder, daß Du in einer Endlosschleife landest.

    Schreib ich nur das > dann baut er mir alle paar Versuche ein
    "undefined" in die Seite ein anstelle des Banners. Ich geh mal davon
    aus, daß das Array an dieser Stelle nicht definiert ist, kann jedoch
    nicht ganz nachvollziehen, warum. Wie krieg ich das weg ???

    Das liegt daran, daß die Indizes eines Feldes von 0 bis Länge-1 laufen, nicht von 1 bis Länge. Dieses Verständnisproblem tritt wohl recht häufig auf. Schau Dir mal die folgende Kette an:

    0 1 2 3 4 5

    Wieviele Zahlen sind das? Fünf? Nein, sechs. Die Länge dieser Kette ist also sechs, die letzte Zahl ist aber fünf, weil auch die Null am Anfang als Zahl zählt.

    Das Problem ist wiederum die Zeile, die auch schon zur Endlosschleife führt:

    Laenge = Banner.length;

    Laenge benutzt Du dann (indirekt) als Index für das Bannerfeld. Wie Du oben gesehen hast, ist Laenge aber eine Nummer zu groß. Daß der Fehler nur alle Nase lang auftritt, liegt an der Zufallsfunktion dazwischen, die Laenge nochmal bearbeitet.

    Dann zum dritten Problem: Welchen Sinn soll die Schleife haben? Du berechnest da x-mal eine Zufallszahl. Meinst Du nicht, daß es egal sein sollte, ob man einmal eine Münze wirft oder zehnmal? Kurz: Die ganze Schleife kann weg.

    Zusammengefasst sieht das alles dann so aus:

    document.write(Banner[Math.round(Math.random(Banner.length-1))]);

    Gruß,
      soenk.e

    1. Hallo Sönke,

      document.write(Banner[Math.round(Math.random(Banner.length-1))]);

      da kriegt Mario immer nur die Elemente 0 und 1. Math.random() kennt keine Parameter.

      Wenn dann sollte die Zeile heißen:

      document.write(Banner[Math.floor(Math.random()*Banner.length)]);

      Für Mario:

      Math.random() ergibt eine Zufallszahlen größer gleich 0 und kleiner 1
      Math.random()*Banner.length ergibt eine Zufallszahl zwischen 0 und der Anzahl der Elemente im Array Banner

      bei 6 Elementen also zwischen 0 und 5,99...

      Math.floor() rundet ab, so das du eine ganze Zahl erhälst (z.B. 0,1,2,3,4,5), welche dann als Index in das Array eingehen kann.

      Viele Grüße

      Antje

      1. document.write(Banner[Math.round(Math.random(Banner.length-1))]);

        da kriegt Mario immer nur die Elemente 0 und 1. Math.random() kennt keine Parameter.

        Hoppla, Verzeihung.

        Wenn dann sollte die Zeile heißen:

        document.write(Banner[Math.floor(Math.random()*Banner.length)]);

        Math.random() ergibt eine Zufallszahlen größer gleich 0 und kleiner 1

        Nachdem ich im ECMAScript-Standard nachgeschaut habe, stimmt das zwar auch, muß aber bemängeln, daß es in SelfHTML etwas anders aussieht :)

        Aber ob's nun floor() & length oder round() & length-1 lautet, ist doch IMHO wurscht.

        Gruß,
          soenk.e

        1. Hallo Sönke

          Nachdem ich im ECMAScript-Standard nachgeschaut habe, stimmt das zwar auch, muß aber bemängeln, daß es in SelfHTML etwas anders aussieht :)

          in SELFHTML steht was in der Netscape-Doku steht. Also eine Zufallszahl zwischen 0 und 1.

          Aber ob's nun floor() & length oder round() & length-1 lautet, ist doch IMHO wurscht.

          nein, ist es nicht

          da die Länge eines Arrays durchaus 0 sein kann, kann eine negative Zahl entstehen.

          Round hat aber einen weiteren Nachteil. Die Zufallszahlen sind nicht mehr gleichverteilt.

          Hier mal ein kleines Script, welches dieses Verhalten demonstriert:

          runden=new Array(0,0,0,0,0,0);
           abrunden=new Array(0,0,0,0,0,0);

          for (i=0;i<20000;i++)
           {
            zufallszahl=Math.random();
            runden[Math.round(zufallszahl*5)]++;
            abrunden[Math.floor(zufallszahl*6)]++;
           }
           document.write("Runden: ",runden,"<br><br>Abrunden: ",abrunden)

          Obwohl jeweils die gleiche Zufallszahl verwendet wurde, sieht das Ergebnis so aus:

          Runden: 1981,3978,4027,3967,3963,2084

          Abrunden: 3307,3340,3339,3293,3283,3438

          Grund sind die Rundungsregeln, was in diesem Fall bedeutet:

          auf 0 wird gerundet, wenn der Wert zwischen 0 und 0,5 liegt
          auf 1, wenn der Wert zwischen 0,5 und 1,5 liegt ...
          auf 6, wenn der Wert zwischen 5,5 und 6 liegt.

          Viele Grüße

          Antje

          1. Nachdem ich im ECMAScript-Standard nachgeschaut habe, stimmt das zwar auch, muß aber bemängeln, daß es in SelfHTML etwas anders aussieht :)

            in SELFHTML steht was in der Netscape-Doku steht. Also eine Zufallszahl zwischen 0 und 1.

            Eben. Wenn bei "zwischen 0 und 1" die Null dazugehört, könnte man davon ausgehen, daß auch die Eins dazugehört - oder andersrum Null und Eins nicht mit drin sind.
            Bei ECMA heißt's dagegen wesentlich eindeutiger: "greater than or equal to 0 but less than 1".

            Gruß,
              soenk.e

            1. Hi Sönke,

              Eben. Wenn bei "zwischen 0 und 1" die Null dazugehört, könnte man davon
              ausgehen, daß auch die Eins dazugehört - oder andersrum Null und Eins
              nicht mit drin sind.

              heutzutage lernt halt niemand mehr, wie CPUs funktionieren.

              Überlege doch mal, was für eine Zahldarstellung zugrunde liegen muß,
              dann ist sofort klar, wieso die Null dazu gehört und die 1 nicht.
              (Das ist eine unnormalisierte Mantisse einer Zahl mit binärem Exponent 0,
              und die kann eben Werte zwischen 0.....0 und F.....F annehmen.)

              Viele Grüße
                    Michael

  2. Krasse Sache. Erstmal danke an Euch beide. Antjes Skript funzt einwandfrei, da von Sönke hab ich jetzt nicht ausprobiert, trotzdem danke. Aber wenn mir nochmal jemand den Unterschied zwischen den beiden Skripten erklären kann ???

    So. Und dann noch ein Lob an Antje. Dein JS Buch ist wirklich toll, habs gerade vor mir liegen und damit hab ich JS relativ einfach gelernt, auch wenn ich noch diese Anfänger Fehler mache. Das Ursprungsskript, was den Fehler hat, hab ich übrigens aus dem Buch, aber ich denk, ich weiß jetzt, daß ich einfach nur hätte 1 abziehen müssen, um den von mir gewünschten Effekt zu erzielen... ;-) Hast Du noch mehr Bücher geschrieben ??? Dein Schreibstil ist nämlich echt super. Und kann ich mir die Skripte aus dem Buch noch irgendwo downloaden, hab sie nämlich nirgends gefunden.

    Trotzdem Dank an Euch beide.
    Gruß, Mario.

    1. Hallo Mario

      Krasse Sache. Erstmal danke an Euch beide. Antjes Skript funzt einwandfrei, da von Sönke hab ich jetzt nicht ausprobiert, trotzdem danke. Aber wenn mir nochmal jemand den Unterschied zwischen den beiden Skripten erklären kann ???

      Sönkes erstes Beispiel war fehlerhaft, da keine Multiplikation stattfand. Im weiteren Verlauf ging es um die Genauigkeit der erzeugten Zufallszahl und da erzeugt Math.floor() eine Gleichverteilung.

      So. Und dann noch ein Lob an Antje. Dein JS Buch ist wirklich toll, habs gerade vor mir liegen und damit hab ich JS relativ einfach gelernt, auch wenn ich noch diese Anfänger Fehler mache.

      :-) Danke, aber jeder hat mit Fehlern angefangen und aus Fehlern lernt man nur.

      Das Ursprungsskript, was den Fehler hat, hab ich übrigens aus dem Buch, aber ich denk, ich weiß jetzt, daß ich einfach nur hätte 1 abziehen müssen, um den von mir gewünschten Effekt zu erzielen... ;-)

      Weißt du, das du versucht hast die Funktion deinen Zwecken anzupassen freut mich am meisten. Du hättest dir es auch einfach machen können und die fertige Funktion (S.213 und folgende) verwenden können.

      Hast Du noch mehr Bücher geschrieben ??? Dein Schreibstil ist nämlich echt super. Und kann ich mir die Skripte aus dem Buch noch irgendwo downloaden, hab sie nämlich nirgends gefunden.

      Gegenwärtig arbeite ich an einem zweiten Buch. Diesmal handelt es sich nicht um JavaScript. Mehr wird jedoch nicht verraten.

      Die Scripte zum Buch kannst du dir hier holen:

      http://pc-anfaenger.de/ressourcen/script.zip

      Viele Grüße

      Antje

      1. Hoff mal, Du widmest Dich PHP, das will ich nämlich als nächstes lernen und mit einem Buch von Dir, kein Problem... ;-) Viel Erfolg für die Zukunft und nochmal danke. Übrigens auch an Sönke.