It should be cross-platform and work with 32-bit and 64-bit compilations. It it is setup just for pointer (integer) sized values, which means if you need it to work with an unsigned quad in a 32-bit compilation it won't work as it currently is but all other size integers should work in 32-bit and all sizes in 64-bit.
Code: Select all
;File Name: Boolean unsigned integer comparisons.pbi
;Author: Demivec
;Created: 03/07/2017
;Version: v00.01
;OS: Windows, Linux, Mac (Only tested for Windows OS)
;Compiler: Compiler: PureBasic v5.44 LTS x64 (or PureBasic v5.44 LTS x32)
;License: Free to use and modify and comes without any guarantees of functionality or freedom from defects
;Forum: http://www.purebasic.fr/english/viewtopic.php?f=12&t=68050
;Description: Boolean comparisons for unsigned integers.
;
; Each function makes a comparison between its arguments (each treated as unsigned integers)
; and returns either 1 if the comparison is true or 0 if it is false.
;
; The four basic comparisons implemented are:
;
; uIsLTEQ() ;'Is Less Than or Equal To'
; uIsGT() ;'Is Greater Than'
; uIsGTEQ() ;'Is Greater Than or Equal To'
; uIsLT() ;'Is Less Than'
;
; Each function was implemented on it's own and not in terms of each other. For example,
; uIsLTEQ() could have been implemented as 'Not uIsGT()', but wasn't.
;
; PureBasic comparisons for 'Equal To' and 'Not Equal To' are the same for both signed and unsigned
; values when the arguments are of the same type and thus don't require any special implementations.
;
; This set of functions were implemented to make more accurate comparisons between address pointers
; without worry with regard to whether the addresses involved crossed over from positive to negative
; values when interpreted as signed values (the way PureBasic deals with all integer values).
;
; Hopefully this accomplishes that. ;)
;performs unsigned 'Is Less Than or Equal To' comparison
Procedure.i uIsLTEQ(val_1.i, val_2.i)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
XOr edx, edx
MOV eax, 1
MOV ecx, val_1
CMP ecx, val_2
CMOVA eax, edx
CompilerElse
XOr rdx, rdx
MOV rax, 1
MOV rcx, val_1
CMP rcx, val_2
CMOVA rax, rdx
CompilerEndIf
DisableASM
ProcedureReturn
EndProcedure
;performs unsigned 'Is Greater Than' comparison
Procedure.i uIsGT(val_1.i, val_2.i)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
XOr edx, edx
MOV eax, 1
MOV ecx, val_1
CMP ecx, val_2
CMOVNA eax, edx
CompilerElse
XOr rdx, rdx
MOV rax, 1
MOV rcx, val_1
CMP rcx, val_2
CMOVNA rax, rdx
CompilerEndIf
DisableASM
ProcedureReturn
EndProcedure
;performs unsigned 'Is Greater Than or Equal To' comparison
Procedure.i uIsGTEQ(val_1.i, val_2.i)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
XOr edx, edx
MOV eax, 1
MOV ecx, val_1
CMP ecx, val_2
CMOVB eax, edx
CompilerElse
XOr rdx, rdx
MOV rax, 1
MOV rcx, val_1
CMP rcx, val_2
CMOVB rax, rdx
CompilerEndIf
DisableASM
ProcedureReturn
EndProcedure
;performs unsigned 'Is Less Than' comparison
Procedure.i uIsLT(val_1.i, val_2.i)
EnableASM
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
XOr edx, edx
MOV eax, 1
MOV ecx, val_1
CMP ecx, val_2
CMOVNB eax, edx
CompilerElse
XOr rdx, rdx
MOV rax, 1
MOV rcx, val_1
CMP rcx, val_2
CMOVNB rax, rdx
CompilerEndIf
DisableASM
ProcedureReturn
EndProcedure
CompilerIf #PB_Compiler_IsMainFile
;demo
Procedure test(a, b)
If uIsLTEQ(a, b)
Debug "$" + Hex(a) + " <= $" + Hex(b)
Else
Debug "$" + Hex(a) + " > $" + Hex(b)
EndIf
If uIsGT(a, b)
Debug "$" + Hex(a) + " > $" + Hex(b)
Else
Debug "$" + Hex(a) + " <= $" + Hex(b)
EndIf
If uIsLT(a, b)
Debug "$" + Hex(a) + " < $" + Hex(b)
Else
Debug "$" + Hex(a) + " >= $" + Hex(b)
EndIf
If uIsGTEQ(a, b)
Debug "$" + Hex(a) + " >= $" + Hex(b)
Else
Debug "$" + Hex(a) + " < $" + Hex(b)
EndIf
Debug "---------------"
EndProcedure
test(0, 1)
test(0, 0)
test(1, 0)
test(-3, 5) ;arguments are treated as unsigned
test(5, -3) ;arguments are treated as unsigned
;A test with pointers and a possible problem situation
Debug "-------Without unsigned comparisons------"
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
*ReadByte = $7FFFFFF8 ;near boundary x86
CompilerElse
*ReadByte = $7FFFFFFFFFFFFFF8 ;near boundary x64
CompilerEndIf
*ReadEnd = *ReadByte + 16 ;go past boundary
While *ReadByte < (*ReadEnd - 3)
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Debug Hex(*ReadByte, #PB_Long)
CompilerElse
Debug Hex(*ReadByte, #PB_Quad)
CompilerEndIf
*ReadByte + 1
Wend
Debug "-------With unsigned comparisons---------"
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
*ReadByte = $7FFFFFF8 ;near boundary x86
CompilerElse
*ReadByte = $7FFFFFFFFFFFFFF8 ;near boundary x64
CompilerEndIf
*ReadEnd = *ReadByte + 16
While uIsLT(*ReadByte, (*ReadEnd - 3))
CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
Debug Hex(*ReadByte, #PB_Long)
CompilerElse
Debug Hex(*ReadByte, #PB_Quad)
CompilerEndIf
*ReadByte + 1
Wend
CompilerEndIf