Grenzen der Number in Gupta

Im Grunde ist der Datentyp Number in Gupta eine feine Sache. Man muss sich nicht mit int, float, double, decimal etc. herumschlagen wie bei vielen anderen Programmiersprachen. Es gibt nur Number. Und im normalen Entwickleralltag kommt man damit bestens zurecht. Aber nicht immer ist Alltag. Manchmal stößt man an Grenzen. Neulich war es mal wieder soweit.

Number als Bitfeld

Es ist sicher nicht ungewöhnlich, wenn man mehrere Bits als Flags in einer Numbervariablen zusammenfasst. Üblicherweise fragt man diese mit

If( nSomeFlags & SOME_SettingsFlag)

ab, wobei SOME_SettingsFlag eine Konstante mit einem Bitwert 2^n ist.

Neulich hatten wir der SOME_SettingsFlag-Konstante den Wert 2^33 zugeordnet. An sich kein Problem für Numbervariablen. Wendet man aber den &-Operator darauf an, kommt als Ergebnis in jedem Fall der Wert 0 zurück.

Ups.

Also schnell mal in der Hilfe nachgeschlagen – sowohl den Operator „&“ als auch den Datentyp „Number“: Leider steht da nichts über Wertebereiche in denen die beiden verlässlich funktionieren. Also habe ich mal ein wenig geforscht.

 & und | können nur 4 Byte

Bei den bitwise And- und Or-Operatoren (& und | ) ist der Fall schnell geklärt: Die funktionieren im Bereich 0x00000000 bis 0xFFFFFFFF. Alles was darüber ist, wird abgeschnitten.

Number ist bis 52 Bits zuverlässig

Welche größte Ganzzahl kann man in Number speichern? Da hinter der Number-Variablen eine Gleitkommazahl steckt, hängt die Antwort von der Länge der Mantisse ab. Ein kurzer Test im Debugger zeigt, dass die Darstellung von Zahlen ab > 2^52 in der Variable-Watch in Exponentialschreibweise ausgeben wird. Ein Blick in Wikipedia erhärtet den Verdacht: Die Norm IEEE 754 sieht für Gleitkommazahlen vom Typ double 52 Bit für die Mantisse vor, elf für den Exponenten und eines für das Vorzeichen – macht insgesamt 64 Bit. Prinzipiell kann man also in Number Ganzzahlen(!) bis 52 Bit speichern. Der Wertebereich erstreckt sich also bis +-(2^53-1) oder  +-9.007.199.254.740.991 oder ungefähr plus minus neun Billiarden.

Erstens kommt es anders

Beim Erstellen einer Funktion, die bitwise-Operationen auch für Zahlen >32 Bit durchführen kann, habe ich u.a. folgende Zeile geschrieben

Set nLower = nOperand & 0xFFFFFFFF

mit folgendem Ergebnis: Beim Testen mit nOperand = 2^52 wirft die Gupta-Runtime eine Fehlermeldung.

Hä?

Bei nOperand = 2^33 bekommt man klaglos eine 0 zurück, obwohl auch diese Zahl für den &-Operator zu groß ist. Weitere Tests haben ergeben, dass man für Zahlen bis 48 Bit keine Fehlermeldung zurückbekommt, alles was darüber liegt produziert eine.

Zweitens als man denkt

Der &-Operator hat also drei Wertebereiche für seine Operanden

  1. 0 – 2^32 – funktioniert fehlerfrei
  2. 2^33 – 2^48 – ignoriert Bits jenseits von 32
  3. > 2^48  – gibt eine Fehlermeldung aus

Fazit

Zwar kann man Ganzzahlen bis +-2^53-1 in Gupta verwenden, aber es ist ratsam sich auf 32 Bit zu beschränken. Denn die bitwise-Operatoren funktionieren nur mit maximal 4 Bytes. Auch die Windows-Message-Parameter wParam, lParam und der Rückgabewert sind auf 32 Bit beschränkt.

Happy coding.

Advertisements

Über thomasuttendorfer
Ich bin Entwicklungsleiter bei der Softwarefirma [ frevel & fey ] in München. Wir entwickeln Business-Software für Verlage und verwenden dafür den Gupta Team-Developer sowie Visual Studio.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: