none
Endlose Kommazahlen RRS feed

  • Allgemeine Diskussion

  • Hallo, ich hab folgende(s) Frage/Problem : Ich hab ein Programm, dass PI annäherungsweise ausrechnet. Dafür benutze ich die Monte Carlo Methode (http://de.wikipedia.org/wiki/Monte-Carlo-Algorithmus)

    Ich habe also folgenden Code in einer Schleife, die die ganze Zeit läuft:

     

    double x = r.NextDouble();
    double y = r.NextDouble();
    
    if ((x * x) + (y * y) <= 1)
    {
      InnerPoints++;
    }
    else
    {
     OuterPoints++;
    }
    

     

    Und dann wird Pi so berechnet:

     

    PI = ((decimal)InnerPoints / (decimal)AllPoints) * 4;
    

     

    InnerPoints hat den Datentyp "long".

    Jetzt habe ich mür überlegt, dass bei einer sehr lagen laufzeit des Programms irgendwann der Höchstewert für long, oder die Genauigkeitsgrenze für "Decimal" erreicht ist.

     

    Also stelle ich mir jetzt die Frage, wie man eine theoretisch unendlich große Zahl als Variable speichern kann, die auch Kommastellen unterstützt. Deshalb kommen auch Lösungen wie "BigInteger" oder "IntX" nicht in Frage, da diese keine Dividierung in Kommazahlen unterstützen.

     

    Mir ist natürlich klar, dass dieses Programm niemals "unendlich" viele Stellen ausrechnen werden kann, aber mich würde mal ein Lösungsansatz für die theoretisch unendlich großen Zahlen interessieren


    • Bearbeitet Ahn1 Mittwoch, 13. April 2011 13:42
    Mittwoch, 13. April 2011 13:18

Alle Antworten

  • hi,

    du brauchst einen Typen, der dazu in der Lage ist. Siehe dir mal BigNumber an:

    http://bignumber.codeplex.com/


    Microsoft MVP Office Access
    https://mvp.support.microsoft.com/profile/Stefan.Hoffmann
    Mittwoch, 13. April 2011 13:35
  • Hallo A.,

    • Deshalb kommen auch Lösungen wie "BigInteger" oder "IntX" nicht in Frage, da diese keine Dividierung in Kommazahlen unterstützen.

    IMHO zum Teil schon, BigInteger kannst Du dafür nehmen.
    Du kannst Dir dann (zum Beispiel) ein Klasse erstellen, die zusätzlich zum BigInteger die Kommaverschiebung (gem. wissenschaftlicher Notation - zum Beispiel als int) mit berücksichtigt.
    Also gemäß der Rückführbarkeit:   123 / 0.05 == 12300 / 5     (und eine Divide-Methode für BigInteger hat man ja).
    Im Prinzip hast Du dann virtuell: "unendlich" viele Stellen. 

    Theorie dazu u.a.:
    [Arbitrary-precision arithmetic - Wikipedia, the free encyclopedia]
    http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic

    Library:

    [C# BigInt, BigFloat library - a free arbitrary precision library for C#]
    http://www.fractal-landscapes.co.uk/bigint.html
    (und Dein Wunsch nach der Zahle PI ist dort auch schon über "BigFloat.GetPi()" gemäß "Gauss–Legendre" Algorithmus umgesetzt)


    ciao Frank
    Mittwoch, 13. April 2011 13:46
  • Also ich hab mir jetzt folgende funktion geschrieben.

    Ich brauche die Kommazahl ja in diesem Fall nur zum Anzeigen als string.

    public class BigIntHelper
      {
        public static string Divide(BigInteger a, BigInteger b)
        {
          string output = "";
    
          BigInteger Rest;
          BigInteger Value = BigInteger.DivRem(a, b, out Rest);
    
          output += Value.ToString();
    
          if (Rest == BigInteger.Zero)
          {
            return output;
          }
          else
          {
            output += ",";
          }
    
          List<BigInteger> Decimals = new List<BigInteger>();
          while (true)
          {
            if (Rest == 0)
            {
              return output;
            }
    
            //Periodenzahlen abfangen
            if (Decimals.Contains(Rest))
            {
              return output;
            }
    
            Decimals.Add(Rest);
    
            Rest = Rest * 10;
    
            output += (BigInteger.DivRem(Rest, b, out Rest));
    
          }
    
        }
      }
    

     

    Was meint ihr dazu?

    Mittwoch, 13. April 2011 16:34
  • Hallo A.,

    also Divide(BigInteger.Parse("1"), BigInteger.Parse("3")) sollte aber zum Beispiel IMHO nicht 0,3 sein, sondern 0,33333 etc.
    Da musst Du es wissen, ob Dir Deine Darstellung da reicht.
    Wenn Du PI performant (hochstellig) berechnen willst, ist wohl ggf. die BigFloat Library (s. mein erstes Posting) sinnreicher.


    ciao Frank

     

    Mittwoch, 13. April 2011 21:04