ich habe es in ähnlicher Form auch schon im englischen Forum geschrieben, die Problematik jetzt aber noch etwas eingegrenzt.
Es geht zum einen um einen offenbaren Fehler und zum anderen habe ich eine generelle Frage.
Purebasic unterstützt nur wenige vorzeichenlose Datentypen. Die, die es unterstützt sind in meine Augen auch nur Krücken, da es sich hier um die Datentypen .a (Ascii), .u (Unicode) und .c (Char). Allesamt keine Datentypen deren Namen auf die Verwendung mit Zahlen hinweisen.
Nutzt man einen vorzeichenbehafteten Datentypen wie z.B. .b (Byte), dann gestalten sich Abfragen wie die folgenden schwer:
Code: Alles auswählen
Define Wert.b = $ff
If $03 > Wert Then ... Mach was
EndIf
Um das zu umgehen, habe ich die Variable bei einem Vergleich bisher immer mit "& $ff" maskiert.
Code: Alles auswählen
Define Wert.b = $ff
If $03 > Wert & $FF Then ...
In einem aktuellen Projekt (und nachdem ich auf ein 64 Bit OS umgestiegen bin) sind mir hier Ungereimtheiten aufgefallen. Daher habe ich mir zwecks Prüfung meiner "Ausmaskierungen" folgenden Testcode geschrieben.
Code: Alles auswählen
; Compile this in x86 mode and then in x64 mode
EnableExplicit
Define b.b
Define w.w
Define l.l
Define q.q
b = $ff
w = $ffff
l = $ffffffff
q = $ffffffffffffffff
Debug "Byte: " + Str(b)
Debug "Byte: " + Str(b & $ff)
Debug b & $ff
Debug "----------------------"
Debug "Word: " + Str(w)
Debug "Word: " + Str(w & $ffff)
Debug w & $ffff
Debug "----------------------"
Debug "Long: " + Str(l)
Debug "Long: " + Str(l & $ffffffff)
Debug l & $ffffffff
Debug "----------------------"
Debug "Quad: " + Str(q)
Debug "Quad: " + Str(q & $ffffffffffffffff)
Debug q & $ffffffffffffffff
Kompiliert man diesen im 64 Bit Modus, dann bekommt man folgendes Ergebnis:
Code: Alles auswählen
[21:35:38] [Debug] Byte: -1
[21:35:38] [Debug] Byte: 255
[21:35:38] [Debug] 255
[21:35:38] [Debug] ----------------------
[21:35:38] [Debug] Word: -1
[21:35:38] [Debug] Word: 65535
[21:35:38] [Debug] 65535
[21:35:38] [Debug] ----------------------
[21:35:38] [Debug] Long: -1
[21:35:38] [Debug] Long: 4294967295
[21:35:38] [Debug] 4294967295
[21:35:38] [Debug] ----------------------
[21:35:38] [Debug] Quad: -1
[21:35:38] [Debug] Quad: -1
[21:35:38] [Debug] -1
Code: Alles auswählen
[21:35:38] [Debug] Byte: -1
[21:35:38] [Debug] Byte: 255
[21:35:38] [Debug] 255
[21:35:38] [Debug] ----------------------
[21:35:38] [Debug] Word: -1
[21:35:38] [Debug] Word: 65535
[21:35:38] [Debug] 65535
[21:35:38] [Debug] ----------------------
[21:35:38] [Debug] Long: -1
[21:35:38] [Debug] Long: 4294967295
[21:35:38] [Debug] -1
[21:35:38] [Debug] ----------------------
[21:35:38] [Debug] Quad: -1
[21:35:38] [Debug] Quad: -1
[21:35:38] [Debug] -1
Hier scheint beim 32 Bit Compiler also bereits das Ausmaskieren eines Longwertes fehlzuschlagen. Und zwar nur, wenn man diesen Wert direkt für einen Vergleich nutzt. Wird das selbe Konstrukt (l & $ffffffff) an eine PureBasic-Funktion übergeben, hier die Str()-Funktion, dann wird die Ausmaskierung des Vorzeichens korrekt beachtet.
Fred hat in diesem Thread geschrieben, das alle Nummern PB-intern als Quad behandelt werden. Das würde sich mit dem Phänomen decken, dass die Ausmaskierung bei Übergabe an eine PB Funktion funktioniert. Offenbar gilt das jedoch nicht für die direkte Ausgabe per Debug, denn da wird trotz & $ffffffff eine -1 ausgegeben.
Das Problem habe ich erst bemerkt, als ich mein Projekt testweise als 32 Bit Exe habe compilieren lassen. In meinen Augen ist das ein Bug, was denkt ihr?
Da ich später mit großen Nummern hantiere, brauche ich auch eine Lösung für Quads. Das funktioniert ja offenbar weder mit 32 Bit noch mit 64 Bit, da es keinen größeren Datentyp gibt. Hat hierzu schon mal jemand eine Lösung erarbeitet?