Vor einiger Zeit gab es im Forum „Office-Lösung“ eine sehr interessante Diskussion, wie in Excel der Wert von 80 ^ 200 ausgerechnet werden könnte. Mit Excel Bordmitteln ist dies leider so ohne weiteres nicht möglich, denn Excel schneidet Berechnungsergebnisse ab der 15. Stelle ab bzw. rundet diese auf oder ab. Auch eine Implementierung per VBA unter Verwendung der Standarddatentypen „Long“, „Single“ oder „Double“ ist nur bedingt möglich, denn der Wertebereich von Variablen dieser Typen ist begrenzt.
Heinz Schweigert, User des Forums, hatte damals im Thread vorgeschlagen, ob denn nicht meine experimentelle VBA-Anwendung „Karatsuba Algorithmus in VBA“ zur Berechnung von 80 ^ 200 verwendet werden könnte. Diese Anwendung bildet große Zahlen als „String“ ab und umgeht somit die Beschränkungen der anderen Datentypen. Nachteil ist jedoch, dass dann die Grundrechenarten zum Addieren und Subtrahieren selbst implementiert werden müssen.
Mein Code in dieser Anwendung war jedoch speziell zur Multiplikation von Zahlen mit sich selbst entwickelt worden, weshalb der Code noch entsprechend angepasst werden musste. Heinz hatte dies freundlicherweise zum Teil übernommen und eine angepasste Version dem Forum zur Verfügung gestellt, welche sehr schnell 80 ^ 200 ausrechnen konnte.
Dieser Artikel läutet eine Artikelserie ein, in welchen ich pro Artikel eine VBA Funktion für die Grundrechenarten mit großen Zahlen vorstellen werde. Anschließend wird ein Add-In erstellt werden, das die Funktionen komfortabel als Formel zur Verfügung stellt und dann auch zum Download bereit stehen wird. Schließlich plane ich das Add-In um weitere komplexere Rechenarten zu erweitern; wobei dies nur im Rahmen der mir zu Verfügung stehenden Zeit geschehen kann.
So nebenbei, Ziel des Add-Ins ist es nicht, gigantische Zahlen auszurechnen oder irgendwelche Rekorde zu brechen; dafür gibt es spezialisierte Programme. Das Ziel des Add-Ins ist es eher, über hinreichend schnelle Routinen im Alltag den Umgang mit großen Zahlen erleichtern.
Addition von großen Zahlen in Excel
Den Anfang macht heute eine Funktion zum Addieren von großen Zahlen. An dieser Stelle nochmal ein Danke schön an Heinz Schweigert für seine Ideen zur Verbesserung des Originalcodes.
Da ich ja, wie zuvor erwähnt, große Zahlen in Variablen vom Typ „String“ ablege, musste eine eigene Routine zur Addition der Zahlen implementiert werden. Das Grundprinzip einer ersten Version meiner Funktion beruhte darauf, die zwei zu addierenden Zahlen ziffernweise von rechts nach links zu addieren. Das funktioniert auch prima, allerdings, wenn wir eine Länge von, sagen wir mal 500 Zeichen pro Eingangsparameter voraussetzen, würde die Schleife zum Addieren der einzelnen Ziffern insgesamt 500 mal durchlaufen.
Eine Menge Schleifendurchläufe kann jedoch dann eingespart werden, wenn nicht die einzelnen Ziffern addiert werden, sondern die Eingangswerte in Blöcke aufgeteilt werden und diese addiert werden. Wenn wir annehmen, die Blocklänge wäre 10 Ziffern, würde sich die Anzahl der Schleifendurchläufe von 500 auf nur noch 50 reduzieren, eine erhebliche Einsparung. Und wir können zur Addition dieser Teilblöcke auch die gängigen Datentypen verwenden.
Obere Abbildung zeigt die zwei langen Zahlen X und Y, die addiert werden sollen und geht beispielhaft davon aus, dass die Blocklänge 4 Ziffern beträgt. Werden „2356“ und „8574“ addiert, erhalten wir „10930“ als Ergebnis, das die Blocklänge um ein Zeichen überschreitet, also größer „9999“ ist. Diesen Übertrag müssen wir dann entsprechend dem Ergebnis des nächsten Blocks hinzufügen. Beispiel: der nächste Block ergibt „1245 + 2364 = 3609 + 1 (Übertrag) = 3610“.
Wie zu sehen, ist die Systematik eigentlich recht einfach, schauen wir uns nun mal den Code dazu genauer an:
In einem ersten Schritt innerhalb der Funktion werden die Eingangsparameter „x“ und „y“ auf die Länge geprüft und anschließend in der Variable „lngLength“ die Länge des Parameters festgehalten, der die größte Anzahl an Ziffern beinhaltet.
Die Variable „lngPrecision“ entspricht der Länge eines Blocks. Hier wird geprüft, ob „lngLength“ kleiner einer vordefinieren Konstante ist (im Code mit dem Wert 10 hinterlegt). Wenn ja, dann kann diese Länge für den Block verwendet werden. Wenn nicht, wird der Wert der Konstante verwendet.
Damit es nicht zu einem Fehler bei der Addition der Blöcke kommt, sollte beide Eingangsparameter so verändert werden, dass deren Länge einerseits gleich ist und andererseits auch durch die Blocklänge teilbar ist. Ersteres geschieht durch das Anhängen von Nullen an die Eingangsparameter und Letzteres über die Bedingung „lngLength Mod lngPrecision > 0“.
Danach braucht nur noch die Schleife zur Addition der Blöcke durchlaufen werden. Pro Durchlauf wird das Ergebnis unter Berücksichtigung des Übertrags an das Gesamtergebnis „strResult“ vorne drangehängt.
Und schließlich werden alle eventuell überschüssig entstandenen Führungsnullen vom Ergebnis entfernt. Das war’s eigentlich schon. Gerne freue ich mich über Anregungen oder Verbesserungsvorschläge zum Code, die Sie beispielsweise als Kommentar hier posten können. Im nächsten Artikel geht es um die Subtraktion von zwei großen Zahlen.
Ich habe ein Add-In für Excel geschrieben, das ich gerne zur Verfügung stellen möchte. Es kann u.a. auch große Zahlen Dividieren oder auch Wurzel ziehen: http://www.moments-4ever.de/bignumber
Fehler oder andere Probleme bitte melden!