Hello,
I have written it in a similar form in another thread, but now I narrowed down the problem a little bit.
For me it looks at one point like a bug in the debug output on x86 systems, but let me explain.
Purebasic supports only a few unsigned data types. This ones that it support are in my eyes only crutches, this are the datatypes. a (Ascii),. u (Unicode) and. c (Char). These are no data types whose names refer to the use of numbers.
If you use a signed data type such as e. g. b (byte), compares like the following ones are difficult or error-prone:
Code:
Define Wert.b = $ff
If $03 > Wert Then ... Do stuff
EndIf
Since $ff corresponds to -1 for a signed data type, $03 is greater than $ff (-1) and the compare result is incorrect. To avoid this, I always used to mask the variable with "& $ff" in a comparison.
Code:
Define Wert.b = $ff
If $03 > Wert & $FF Then ...
It works so far.
In a current project (and after I switched to a 64 bit OS) I noticed some inconsistencies here. Therefore I wrote the following test code to check my "masking".
Code:
; 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
The code outputs a "large" byte, word, long and quad value as a pure number with sign, then once as a masked, unsigned number (via Str () function) and once again as a masked, unsigned number directly via debug.
If you compile it in 64 bit mode, you get the following result:
Code:
[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
If you compile it in 32 bit mode, you get this result:
Code:
[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
Note the third debug value at "Long:"
In this case, the masking of a long value already seems to fail with the 32 bit compiler. But only if you use this value directly for a comparison.
Fred wrote that all numbers are treated as a quad within PB. This would coincide with the phenomenon that masking works when transferred to a PB function.
I didn't notice the problem until I had my project compiled as a 32 bit exe file. In my eyes, that's a bug in the debug output, what do you think?
Since I have to deal with large numbers later, I also need a fast solution for comparing unsigned quads. This obviously does not work either with 32 bit or 64 bit, since there is no larger data type. I quickly put together a workaround tonight. But I find my solution via procedure very bad and to slow.
Code:
EnableExplicit
Procedure IsGreaterQ(qNumber1.q, qNumber2.q)
If qNumber1 >> 32 & $ffffffff > qNumber2 >> 32 & $ffffffff : ProcedureReturn #True :EndIf
If qNumber1 >> 32 & $ffffffff < qNumber2 >> 32 & $ffffffff : ProcedureReturn #False :EndIf
If qNumber1 >> 32 & $ffffffff = qNumber2 >> 32 & $ffffffff And qNumber1 & $ffffffff > qNumber2 & $ffffffff
ProcedureReturn #True
Else
ProcedureReturn #False
EndIf
EndProcedure
If IsGreaterQ($04, $ffffffffffffffff)
Debug "greater"
Else
Debug "not greater"
EndIf
If IsGreaterQ($ffffffffffffffff, $fffffffffffffffe)
Debug "greater"
Else
Debug "not greater"
EndIf
Has anyone ever worked out a FAST solution for this damn sign/unsign problem?
PS: WTF? It is also inconsistent during debugging/tracing.
Here I step through the code in x86 mode. The quick display shows me clearly "If 48 > 4294967294" but the comparsion will be executed wrong. 48 is not grater than 4294967294. Also masking does not help at this point.
How to write reasonable programs, if the tool is not able to make a simple comparison of two 4-byte digits? 20 years PureBasic and still no unsigned data types. So far I've rarely been disgusted, but in my current project this really pisses me off. Sorry for the hard words, but I hate to mess up my code with so many workarounds.

