tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
7
ZUGRIFFE
1757
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Avatar von multimolti
    multimolti multimolti ist offline Game Programmer
    Registriert seit
    Jan 2007
    Beiträge
    802
    Hallo!

    Ich brauche für mein Projekt eine Klasse, die extrem präzise und große Zahlen verarbeiten kann. Ich weiß, dass es viele BigInteger und BigNumber Klassen gibt, die können aber alle nicht mit Nachkommastellen rechnen.
    Ich bräuche irgendwas, was mit vielleicht 1000 Nachkommastellen und Zahlen mit 30000 Ziffern rechnen kann und dabei nicht zu viel Speicherplatz braucht (also nicht als String gespeichert wird oder so ein Quatsch). Das Ganze sollte am Besten auch noch schnell rechnen und alle Standardoperationen unterstützen (Addition, Subtraktion, Multiplikation, Division).

    Kennt jemand sowas? Habe im Internet leider nichts gefunden!
     

  2. #2
    vop vop ist offline Mitglied Platin
    Registriert seit
    Mar 2004
    Beiträge
    676
    Wo ist das Problem, wenn die vorhandenen Klassen keine Nachkommastellen verarbeiten?
    Erweitere diese Klassen doch um Nachkomma-Funktionalität, indem du einfach eine Kommaposition einführst, die angibt, wo der Nachkommateil beginnt.
    Die Zahl 123456789012345678901234567890 kann durch Angabe der Info, dass das Komma an Position 20 steht doch als Zahl
    12345657890123456789,01234567890 interpretiert werden.
    Die Rechenoperationen müssen natürlich entsprechend angepaßt werden.

    Wenn du allerdings keine Strings vewrwenden möchtest (Warum nicht?), könntest du natürlich auch ein Array von bytes nehmen und dann bitweise rechnen. Das macht dann wohl noch etwas mehr Arbeit.

    Interessant finde ich die Frage, warum du Zahlen mit 30k Ziffern berechnen willst und das mit einer Genauigkeit von 1000 Nachkommastellen?
    Mir fällt beim besten Willen keine Fall ein, wo so etwas Sinn macht.
     

  3. #3
    Avatar von multimolti
    multimolti multimolti ist offline Game Programmer
    Registriert seit
    Jan 2007
    Beiträge
    802
    Erst mal Danke für deinen Vorschlag.

    Darüber habe ich auch schon nachgedacht, mich dann jedoch dagegen entschieden, da das sehr viel aufwand machen würde. Ich verwende bisher die BigInteger-Klasse von Codeproject, mit der klappt das für Integer alles super, nur verstehe ich leider nicht, wie die das intern speichert.
    Das läuft irgendwie so: Die Zahl, die man eingibt, wird in Teile gesplittet die in uint reinpassen, also 9-10 Ziffern. Nur hätte ich gedacht, dass die Zahl 12345678910111213 dann nach der 0 gesplittet wird, also 12345678910 und 111213 und jeder Teil in das uint-Array geschrieben wird. Leider macht die Klasse aus der oben genannten Zahl aber 1576189421 und 2874452. Das macht für mich keinen Sinn, ich habe auch schon den Code angeschaut aber komme nicht drauf, wie die das machen.

    Daher suche ich einfach eine fertige Klasse, die das schon kann.

    Und zur Anwendung:
    Ich kann dir so viel sagen, ich will eine Kurve durch viele Punkte legen, sagen wir so 5000 Stück. Um das zu lösen brauche ich eine Matrix, die dann mit dem Gauss-Verfahren gelöst wird. Bei 5000 Punkten hat diese Matrix die Dimension 5000x5001, also 25.005.000 (25 Millionen) Felder. Die Werte der Matrix sind die Potenzen der x-Werte, also wenn mein 1. Punkt (34/0,34) ist, dann steht in der 1. Zeile 1. Spalte 34^4999, in der 2. Spalte 34^4998, usw.
    Da siehst du schon dass die Zahlen ganz schön groß werden
    Jetzt kann ich die leider nicht runden oder so, habe das schon versucht, dann wird das Ergebnis nachher zu ungenau. Selbst bei 8 Punkten und der Präzision von double kann man das Ergebnis schon vergessen. Daher müssen mehr Stellen her!
     

  4. #4
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    es gibt auch Bibliotheken die beliebig genaue Berechnungen ermöglichen (arbitrary precision math) (auch mit beliebig vielen Nachkommastellen)

    Schau doch mal hier:
    http://www.codeplex.com/sine

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  5. #5
    Avatar von multimolti
    multimolti multimolti ist offline Game Programmer
    Registriert seit
    Jan 2007
    Beiträge
    802
    Hey Danke, dieses Sine Ding sieht eigentlich genau nach dem aus, was ich brauche, ist nur leider EXTREM langsam...

    Ich habe mal einen Test gemacht, mit der BigInteger-Klasse von Codeproject und der BigNumDec-Klasse von diesem Sine Dings 5000^2000 auszurechnen. Beide kommen exakt auf den gleichen Wert, nur braucht BigInteger da 35ms für, wobei BigNumDec 4200ms braucht! Das ist so langsam, das kann ich nicht gebrauchen!

    Im Anhang findet ihr das Programm, falls ihr es testen wollt.
    Miniaturansicht angehängter Grafiken Miniaturansicht angehängter Grafiken Extrem präzise Zahlen in C#-bignum.jpg  
    Angehängte Dateien Angehängte Dateien
     

  6. #6
    Avatar von Alexander Schuc
    Alexander Schuc Alexander Schuc ist offline admin | crazy-weasel
    tutorials.de Administrator
    Registriert seit
    Aug 2001
    Ort
    Österreich, Stmk, Graz
    Beiträge
    2.783
    Wie wäre es mit GNU MP wrapper for .NET?
     
    With the first link the chain is forged. The first speech censored, the first thought forbidden, the first freedom denied, chains us all irrevocably.
    Aaron Satie

    Legends... are the spice of the universe, Mr. Data, because they have a way of sometimes coming true.
    Captain Jean-Luc Picard, Stardate ~41294.5

    Tutorials.de chattet. Hier gibts auch .net Support ^^
    Klickt auf chattet und nutzt den Webchat, oder verbindet euch zu irc.tutorials.de - Channel #Tutorials.de

    (moo)blog furred.net // SiteInfo für WP7 // Pastebin für WP7 // BlogEngine.net Extensions

  7. #7
    Registriert seit
    Dec 2001
    Ort
    Bayern
    Beiträge
    5.806
    Blog-Einträge
    5
    Zitat Zitat von multimolti Beitrag anzeigen
    Die Zahl, die man eingibt, wird in Teile gesplittet die in uint reinpassen, also 9-10 Ziffern. Nur hätte ich gedacht, dass die Zahl 12345678910111213 dann nach der 0 gesplittet wird, also 12345678910 und 111213 und jeder Teil in das uint-Array geschrieben wird. Leider macht die Klasse aus der oben genannten Zahl aber 1576189421 und 2874452. Das macht für mich keinen Sinn, ich habe auch schon den Code angeschaut aber komme nicht drauf, wie die das machen.
    Wenn man die Zahlen im Hexadezimalsystem aufschreibt, sieht man es leichter:
    Code :
    1
    2
    3
    
    12345678910111213 = 2BDC545DF2BDEDh
              2874452 = 2BDC54h
           1576189421 =       5DF2BDEDh

    Zitat Zitat von multimolti Beitrag anzeigen
    Und zur Anwendung:
    Ich kann dir so viel sagen, ich will eine Kurve durch viele Punkte legen, sagen wir so 5000 Stück. Um das zu lösen brauche ich eine Matrix, die dann mit dem Gauss-Verfahren gelöst wird. Bei 5000 Punkten hat diese Matrix die Dimension 5000x5001, also 25.005.000 (25 Millionen) Felder. Die Werte der Matrix sind die Potenzen der x-Werte, also wenn mein 1. Punkt (34/0,34) ist, dann steht in der 1. Zeile 1. Spalte 34^4999, in der 2. Spalte 34^4998, usw.
    Da siehst du schon dass die Zahlen ganz schön groß werden
    Jetzt kann ich die leider nicht runden oder so, habe das schon versucht, dann wird das Ergebnis nachher zu ungenau. Selbst bei 8 Punkten und der Präzision von double kann man das Ergebnis schon vergessen. Daher müssen mehr Stellen her!
    Du versuchst hier das Symptom zu bekämpfen und nicht die Ursache. Ich nehme mal an, dass es sich bei der besagten Matrix um die Vandermonde-Matrix handelt und du ein Polynom vom Grad 5000 durch deine Stützpunkte legen willst. Diese Matrix ist nun in der Regel aber extrem schlecht konditioniert, d.h. beim Lösen des Systems schaukeln sich Rundungsfehler immer weiter auf. Abgesehen davon ist der Gauss-Algorithmus zum Lösen eines solch großen Systems eher ungeeignet, da er kubische Laufzeit benötigt. Hier greift man normalerweise auf iterative approximative Lösungsverfahren wie Gauß-Seidel-, Jacobi- oder SOR-Iteration zurück (die aber nicht immer konvergieren, aber das ist eine andere Geschichte). In diesem Fall hilft das aber auch nicht viel, da man der schlecht konditionierten Matrix damit auch nicht entkommt.

    Mein Vorschlag wäre daher, ein anderes Interpolationsverfahren zu verwenden, wie z.B. Spline-Interpolation. Vielleicht helfen dir auch die Folien zur Vorlesung Numerisches Programmieren an der TU München weiter.

    Grüße, Matthias
     
    „Gib einem Menschen einen Fisch, und er wird für einen Tag satt. Lehre ihn Fischen, und er wird ein Leben lang satt.“
    “For every complex problem, there is an answer that is short, simple and wrong.”
    “Pessimism is safe, but optimism is a lot faster!”


    Aktuelles Coding Quiz: #17 - Wörter kreuz und quer

  8. #8
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    mit dem .Net Framework 4 gibts nun auch eine (native) BigInteger Implementierung:
    Code csharp:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Numerics;
     
    namespace De.Tutorials.Training
    {
        class BigIntegerExample
        {
            static void Main(string[] args)
            {
                Console.WriteLine(factorial(5));
                Console.WriteLine(factorial(16));
                Console.WriteLine(factorial(99));
            }
     
            static BigInteger factorial(int n)
            {
                BigInteger result = 1;
                for (int i = 1; i <= n; i++)
                {
                    result *= i;
                }
                return result;
            }
        }
    }

    Ausgabe:
    Code :
    1
    2
    3
    
    120
    20922789888000
    933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000

    Siehe auch:
    http://msdn.microsoft.com/de-de/libr...iginteger.aspx

    Referenz auf System.Numerics Assembly nicht vergessen.

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

Ähnliche Themen

  1. Präzise Maus
    Von Pazu im Forum Photoshop
    Antworten: 17
    Letzter Beitrag: 05.02.06, 18:52
  2. Präzise Kontor erzeugen?
    Von Ogre im Forum Photoshop
    Antworten: 2
    Letzter Beitrag: 21.08.05, 17:21
  3. Kurvenpunkte bearbeiten - wie gehts präzise?
    Von picrasso im Forum Sonstige Grafik-Programme
    Antworten: 5
    Letzter Beitrag: 06.10.04, 11:10
  4. Cool Edit - Delay präzise einstellen
    Von unknownstar im Forum Audiotechnik, Recording & Audio-Software
    Antworten: 6
    Letzter Beitrag: 08.08.04, 17:15
  5. Darstellung extrem großer Zahlen in Pascal
    Von barf im Forum Delphi, Kylix, Pascal
    Antworten: 2
    Letzter Beitrag: 17.05.04, 09:35