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: Select all
Define Wert.b = $ff
If $03 > Wert Then ... Do stuff
EndIf
Code: Select all
Define Wert.b = $ff
If $03 > Wert & $FF Then ...
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: Select all
; 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
If you compile it in 64 bit mode, you get the following result:
Code: Select all
[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: Select all
[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
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: Select all
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
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.