Fragensteller
Endlose Kommazahlen

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
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 -
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_arithmeticLibrary:
[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 -
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?
-
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