Bei einem meiner Hobbys, ProjectEuler versucht man mathematische Probleme mithilfe der Programmierung zu lösen. Dabei greifen viele der dort registrierten Anwender auf professionelle Mathematik-Programme (Mathematica, etc.) zurück.
Ich finde es aber deutlich interessanter, die Probleme selbst zu analysieren und die erzeugten Programmschleifen immer wieder ein wenig zu verfeinern und zu verbessern, bis man innerhalb der geforderten 60 Sekunden auch das korrekte Ergebnis ausgespuckt bekommt.
Als Programmiersprache habe ich mir VB.NET ausgesucht, was gerade für mathematische Probleme oft unnötig Barrieren bereitstellt. So sind Integerzahlen länger als 64 Bit nicht vorgesehen. Programmierer, die sich z.B. in reinem C mit den Problemen beschäftigen, können von „long long“ Datentypen profitieren und einen beträchtlichen Teil der Probleme damit „direkt“ lösen.
Zunächst versuchte ich, simple Rechenaufgaben mit irrsinnig großen Zahlen über Strings zu lösen. Dies funktioniert auch prinzipiell ganz gut, allerdings sind String-Zugriffe nicht sehr schnell und die Implementierungen von effizienten Divisions-, Multiplikations- oder Expontialfunktionen erwies sich als sehr zeitraubend und nicht zielführend.
Bereits in der Zeit als studentische Hilfskraft am Lehrstuhl 6 nutzte ich die die GMP-Library, um Berechnungen mit großen Zahlen effizient durchzuführen. Die Programmierarbeiten, welche auf die libGMP zurückgriffen, waren dabei allesamt in C durchgeführt worden.
Ich kannte also schon den Wert dieser Library, und wollte diese daher auch gerne in meine aktuellen Berechnungen im Rahmen von ProjectEuler einsetzen.
Voraussetzungen
- Lauffähige Visual Studio Umgebung (ich persönlich nutze Visual Studio 2008)
- Eine fertig kompilierte libgmp-3.dll, welche im Projektverzeichnis vorliegt
Für die libgmp-3.dll gibt es hier und hier Anregungen, wie man die DLL erfolgreich unter Windows kompilieren kann.
Wenn alles bereit ist, fügt die libgmpWrapper in euer Projekt mit ein. Ich habe mein Projekt „Problems“ genannt, entsprechend habe ich auch ein Testmodul erstellt, welches die libgmpWrapper importiert und die einfachen Zugriffe darauf demonstriert.
Hinweise!
- Der Wrapper ist noch nicht für alle Fälle stabil, so hat er noch arge Probleme beim Zusammenspiel von Multiplikationen und Potenzierungen.
- Zudem gibt es noch das eine oder andere Speicherleck, welches durch die direkten Zugriffe auf die Variablen verursacht wird. Falls Sie damit Probleme haben, sollten Sie versuchen, auf die notwendigen Berechnungsfunktionen innerhalb der GMP-Library selbst zurückzugreifen.
- Vorsicht beim Zuweisen von Werten zu anderen Variablen. Haben Sie z.B. zwei GMP-Integer-Variablen (mpz) deklariert, sollten Sie diese nicht durch die Zuweisung
links = rechts
kopieren, da hier die Speicherparameter kopiert werden. Eine echte Kopie funktioniert nur über den direkten Zugriff aufmpz_set(links, rechts)
. Ich habe hier noch keine Möglichkeit gefunden, wie man den Wrapper für diesen Spezialfall erweitert. - Manchmal kommt es auch aus noch nicht geklärter Ursache zu Abbrüchen, hierbei wird meist auf bestehende Speicherzellen geschrieben.
GPL-Hinweis
Achtung, für alle auf dieser Webseite veröffentlichten Skripte gilt die GPL v2 – ein entsprechendes Exemplar der Gesamtfassung finden Sie bei GNU.
Copyright (C) 2010 Stefan Magerstedt Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN ZWECK. Details finden Sie in der GNU General Public License. Sie sollten ein Exemplar der GNU General Public License zusammen mit diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA.