wimu: Große Zahlen in Javascript

Hallöle,

ich bin gerade dabei, eine Art point-and-click-Adventure auf javascript-Basis zu programmieren. Um Spielstände abspeichern zu können, habe ich mir folgendes überlegt:

Jedes Ding, das man "aufheben" und in sein "Inventar" legen kann, erhält eine ID, bestehend aus einer Primzahl. Gespeichert wird nun das Produkt dieser IDs zur basis 36 (damit die strings nicht zu lang werden) in einem cookie. "Laden" funktioniert genau umgekehrt; cookie zur basis 10 umrechnen und diese Zahl in Primfaktoren zerlegen. Funktioniert auch alles Prima, bis zur 14. Primzahl (macht 13082761331670030 bzw. 3ktg9l1zle6) und der Algorithmus zur Primfaktorzerlegung ist auch halbwegs fix. Aber ab der 15. Primzahl verrechnet sich das script bereits beim Multiplizieren und sagt, das Produkt sei 614889782588491400 statt der tatsächlichen 614889782588491410. Nun kann doch Javascript angeblich Zahlen bis ca. 1.79e+308 darstellen, aber wie weit kann Javascript ohne Rundungsfehler rechnen? Und ist meine Idee deswegen grundsätzlicher Humbug? Irgendein Tipp, wie ich das umgehen könnte?

Grüße,

WiMu

  1. Hi,

    Jedes Ding, das man "aufheben" und in sein "Inventar" legen kann, erhält eine ID, bestehend aus einer Primzahl. Gespeichert wird nun das Produkt dieser IDs zur basis 36 (damit die strings nicht zu lang werden) in einem cookie.

    nette Idee, aber wusstest Du schon, dass jedes Bit zu jeder Zeit nur ein einziges Mal mit 1 belegt sein kann?

    Cheatah

    --
    X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
    X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
    X-Will-Answer-Email: No
    X-Please-Search-Archive-First: Absolutely Yes
    1. äh ... meinst du in etwa folgendes: es gibt n Dinge, deren Zustand jeweils quasi true und false sein kann; also n-stelligen, binären string erzeugen?
      Hm ... egal, ob du das gemeint hast; so werd' ich's machen *koppklatsch*

      Grüße,

      WiMu

      1. :)

        Ich moechte trotzdem nochmal auf Deine Frage eingehen, wie weit JS ohne Rundungsfehler rechnen kann.

        alert(0.7+0.1);

        Falls das bei Dir 0.8 ergeben sollte:

        for (i=0; i<=1; i=i+0.1)
        {
         alert(i);
        }

        Ich finde: nicht sehr weit. ;)

        --
        "Die Diebesgilde beklagte sich darueber, dass Mumm in aller Oeffentlichkeit behauptet hatte, hinter den meisten Diebstaehlen steckten Diebe."
              - T. Pratchett
        1. Hi,

          Ich moechte trotzdem nochmal auf Deine Frage eingehen, wie weit JS ohne Rundungsfehler rechnen kann.

          ohne das jetzt näher zu beleuchten:

          alert(0.7+0.1);

          An diesem Rundungsfehler ist Gott schuld. Hätte er uns nicht eine so himmelschreiend dämliche Anzahl Finger gegeben, sondern beispielsweise acht Stück[1], gäbe es auch keine derartigen Schwierigkeiten bei der Umrechnung von Binär ins rassenspezifische Zahlensystem.

          Cheatah

          [1] Einschließlich der Daumen.

          --
          X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
          X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
          X-Will-Answer-Email: No
          X-Please-Search-Archive-First: Absolutely Yes
          1. An diesem Rundungsfehler ist Gott schuld.

            Gott existiert, weil die Mathematik widerspruchsfrei ist, und der Teufel existiert, weil wir das nicht beweisen können - Andre Weil.
            Konnt's mir nicht verkneifen ;-)

            Grüße,

            WiMu

            1. Hi,

              Gott existiert, weil die Mathematik widerspruchsfrei ist, und der Teufel existiert, weil wir das nicht beweisen können - Andre Weil.

              "Ach du lieber Gott", sagt Gott, "daran habe ich gar nicht gedacht", und löst sich prompt in ein Logikwölkchen auf.
              -- Douglas Adams

              Konnt's mir nicht verkneifen ;-)

              Dito ;-)

              Cheatah

              --
              X-Self-Code: sh:( fo:} ch:~ rl:| br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
              X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
              X-Will-Answer-Email: No
              X-Please-Search-Archive-First: Absolutely Yes
  2. Die Überlegung hakt ein bisschen. Das Produkt wird nämlich als Zahl ähnlich lang wie wenn du einzelne Zahlen abspeicherst.
    Außerdem, wie willst du dieses riesen Produkt wieder zerlegen? Da hilft dann nur ausprobieren und das ist auch nicht wirklich schön.

    1. Also ich bin ursprünglich auf diese seltsame Idee gekommen, weil ich auch noch die Anzahl der einzelnen IDs (bzw. Gegenstände im Inventar) speichern wollte. Da wäre an und für sich das Produkt schon prima, wegen des Fundamentalsatzes der Arithmetik. Aber dass diese Zahlen dann wirklich astronomisch werden hab' ich ziemlich schnell gemerkt (1000 mal ID 2 entspräche ja 2^1000 oder ca. 1,07e+301 ... z.B. um ein Guthaben von 1000€ mit €=ID2 zu speichern); nur, dass ich dann auf dieses Primzahlenzeug auch problemlos ganz verzichten kann ist mir entgangen ...

      Aber wohlgemerkt hat es nie bei der Rückfaktorisierung Probleme gegeben, sondern seltsamer Weise immer nur bei der Multiplikation.

      Grüße,

      WiMu

    2. OK, vielleicht ist das ja tatsächlich für den ein oder anderen interessant ... Ich hab' das jetzt mal binär ausprobiert. Also wenn ich 100 verschiedene IDs in einem string speichern möchte, wäre das ein 100stelliger string, den ich so nicht in einen cookie packen möchte, sondern wie zuvor zur basis36 umrechne. Zum Testen mal folgendes gemacht:

        
      var binaryString      = '1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';  
      var decimalString     = parseInt(binaryString, 2);  
      var ASCIIString       = decimalString.toString(36);  
      var decimalStringTest = parseInt(ASCIIString, 36);  
      var binaryStringTest  = decimalStringTest.toString(2);  
        
      alert(binaryStringTest);  
      
      

      Ergebnis:

      111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000

      Na Klasse *grmpf*; werde jetzt wohl wirklich einfach Zahlen aneinander hängen ... hoffentlich schafft javascript wenigstens das^^

      Grüße,

      WiMu

      1. Hi!

        :)

        Also hundert Bits sind bei mir grad 12.5 Bytes. Mit schlappen 13 Bytes kannst Du also Deine IDs speichern. Selbst, wenn Du die Zahlen als Strings speicherst, bist du mit Trennzeichen bei maximal 51 Zeichen (Bytes). Du muesstest nur noch umrechnen.

        Du klingst in Deinen Posts so, als koenntest Du Dir die noetigen Funktionen dazu selbst schreiben. Jedenfalls theoretisch.

        --
        "Die Diebesgilde beklagte sich darueber, dass Mumm in aller Oeffentlichkeit behauptet hatte, hinter den meisten Diebstaehlen steckten Diebe."
              - T. Pratchett