Page 1 of 2

Simpliest method compare numbers [Resolved]

Posted: Mon Jan 12, 2026 5:20 pm
by Kwai chang caine
Hello at all

If i have
a=10
b=2
c=3
d=5
and i want the smaller of this four numbers, i must compare each number with < and i have see that i do much instructions for just this simple result :shock:

Code: Select all

If a< b
   If a< c
    Min= a
   EndIf
  ElseIf b< a
   If b< c
    Min= b
   EndIf
  EndIf 
   ....
   .....
   ...
   Debug Min
   
Have you a "Magical" mathematical method, with hieroglyph instructions :mrgreen: , like i see in yours amazing codes and dont' know :oops: , for return the smaller number,

Image

so as not to have to write a page of code to compare a few numbers :|

Have a good day

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 5:37 pm
by jacdelad
Hi KCC,

there are many methods, depending on how your numbers are stored. Like, put them into an array and sort it, take the first value. Create a function that always returns the lower one, store it, compare to the next...

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 5:42 pm
by SPH
Look that KCC :

Code: Select all

cmb=20

Dim bank(cmb)
For i=1 To cmb
  bank(i)=Random(200)
  Debug bank(i)
Next
Debug "==="
;;;

plus_petit=bank(1)

For i=1 To cmb
  If bank(i)<plus_petit
    plus_petit=bank(i)
  EndIf
Next
;;;

Debug plus_petit
Kiss :wink:

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 5:54 pm
by NicTheQuick
Is it always 4 numbers? Or do you want to have a code working for N numbers?
For 4 numbers the easiest solution is that:

Code: Select all

Procedure min4(a, b, c, d)
	Protected min = a
	If b < min: min = b: EndIf
	If c < min: min = c: EndIf
	If d < min: ProcedureReturn d: EndIf
	ProcedureReturn min
EndProcedure

Debug min4(10, 2, 3, 5)
For N numbers you just iterate over all of them and in each loop you check if a new minimum was found.

And if you already have the numbers and you always want to retrieve the lowest number, and after that the next lowest number, and so on, you simply sort them with `SortArray()` or `SortList()`.

And if you also want to be able to add new numbers in between, you should implement a Min-Heap. More information about that you can find at Wikipedia: https://en.wikipedia.org/wiki/Heap_(data_structure)

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 5:55 pm
by Mindphazer
Easier :

Code: Select all

cmb=20

Dim bank(cmb)
For i=1 To cmb
  bank(i)=Random(200)
  Debug bank(i)
Next
Debug "==="
;;;


SortArray(bank(), #PB_Sort_Ascending)
plus_petit=bank(1)


Debug plus_petit

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 6:00 pm
by SMaag

Code: Select all

  Macro Min(_v1, _v2)
    (_v1*Bool(_v1 <= _v2) + _v2*Bool(_v1 > _v2))
  EndMacro
  
  ; Get the highest value from 2 values
  ; use it : result = Max(3,2)
  Macro Max(_v1, _v2)
    (_v1*Bool(_v1 >= _v2) + _v2*Bool(_v1 < _v2))
  EndMacro
  
  Macro MinOf3(_VarResult, _v1, _v2, _v3)
  	If _v3 < _v2
  		If _v3 < _v1
  			_VarResult = _v3
  		Else
  			_VarResult = _v1
  		EndIf
  	ElseIf _v2 < _v1
  		_VarResult = _v2
  	Else
  		_VarResult = _v1
  	EndIf
  EndMacro
  
  ; Write the highest value from 3 values to VarResult
  ; use it: MaxOf3(VarResult, 3, 2, 1)
  Macro MaxOf3(_VarResult, _v1, _v2, _v3)
    If _v3 > _v2
  		If _v3 > _v1
  			_VarResult = _v3
  		Else
  			_VarResult = _v1
  		EndIf
  	ElseIf _v2 > _v1
  		_VarResult = _v2
  	Else
  		_VarResult = _v1
  	EndIf
  EndMacro

a=10
b=2
c=3
d=5

MinOf3(res, a,b,c)
res = Min(res,d)
Debug res

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 6:46 pm
by Kwai chang caine
Thanks a lot my friends for you numerous and quick answers 8) :shock:

@jacdelad
Yes when i have see all this lines, and after have losten in all my < conditions :oops:
I press DELETE touch, and write this :wink:

Code: Select all

 Dim Temp(2)
   Temp(0) = a
   Temp(1) = b
   Temp(2) = c
   Temp(3) = d
   SortArray(Temp(), #PB_Sort_Ascending)
   FreeArray(Temp())
   Debug Temp(0)
@SPH
Salut ma poule :mrgreen: (Hello my chicken)
Not so bad, a little bit like my solution, perhaps faster, i don't know...and furthermore without sorting array 8)

@NicTheQuick
Very nice and clean code
In fact the method like my first code, but you..you have terminate :oops: :lol:

@Mindphazer
We have the same idea.... :wink:
It's surely a question of climate :lol:

@SMaag
As for the hieroglyphs...they're magnificent. :shock:
This is exactly the kind of code that makes me dream 8) ... which is normal, because I fall asleep, after an hour of trying to understand it. :wink:
It's so beautiful, it looks like the ASM code I admire but don't understand a word of, :oops:

Code: Select all

Macro Min(_v1, _v2)
    (_v1*Bool(_v1 <= _v2) + _v2*Bool(_v1 > _v2))
  EndMacro
Waouuuh !!! i love this part, it's jewelry. :shock: Luckily I don't need to fix it. :mrgreen: :lol:
However, for the "short" side... :lol: :wink:

@ALL
Thanks again a lot at you all for your precious help
So apparently there are not specifical mathematical operator for do that

I wish to you all an happy new year 8)

Re: Simpliest method compare numbers [Resolved]

Posted: Mon Jan 12, 2026 7:07 pm
by ChrisR
My macros, pretty close to SMaag's one
Macros are probably the fastest method, but beyond 4 variables, an array may be better

Code: Select all

Macro Min(a, b)
  (Bool(a < b) * a + Bool(a < b)!1 * b)
EndMacro

Macro Max(a, b)
  (Bool(a > b) * a + Bool(a > b)!1 * b)
EndMacro

a=10
b=3
c=2
d=5

Debug Min(Min(Min(a, b), c), d)
Debug Max(Max(Max(a, b), c), d)

Re: Simpliest method compare numbers [Resolved]

Posted: Mon Jan 12, 2026 9:28 pm
by SMaag
Just to see if it works! The 'crazy' Assembler versions!

Code: Select all

EnableExplicit

; works at x32 and x64
; min of 4 Long

; SSE PackedMin support only up to 32 Bit
Procedure Min4l(a.l, b.l, c.l=2147483647, d.l=2147483647)
  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
    
    CompilerIf #PB_Compiler_64Bit
    !XOR RAX, RAX  
    CompilerEndIf
  
    !MOVD XMM0, [p.v_a]  ; XMM0-LoWord = a 
    !MOVD XMM1, [p.v_b]  ; XMM1-LoWord = b 
    !MOVD XMM2, [p.v_c]  ; XMM2-LoWord = c 
    !MOVD XMM3, [p.v_d]  ; XMM3-LoWord = d 
      
    !PMINSD XMM0, XMM1   ; Min(a,b)
    !PMINSD XMM2, XMM3   ; Min(c,d)
    !PMINSD XMM0, XMM2   ; MinOfAll -> XMM0
    !MOVD EAX, XMM0      ; EAX = min
    ProcedureReturn      ; Return EAX/RAX
    
  CompilerElse
    
    If a > b : a = b : EndIf
    If a > c : a = c : EndIf
    If a > d : a = d : EndIf
    ProcedureReturn a
    
  CompilerEndIf
  
EndProcedure

Procedure Max4l(a.l, b.l, c.l=-2147483648, d.l=-2147483648 )
  CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
    CompilerIf #PB_Compiler_64Bit
    !XOR RAX, RAX  
    CompilerEndIf
    !MOVD XMM0, [p.v_a]  ; XMM0-LoWord = a 
    !MOVD XMM1, [p.v_b]  ; XMM1-LoWord = b 
    !MOVD XMM2, [p.v_c]  ; XMM2-LoWord = c 
    !MOVD XMM3, [p.v_d]  ; XMM3-LoWord = d 
      
    !PMAXSD XMM0, XMM1   ; Max(a,b)
    !PMAXSD XMM2, XMM3   ; Max(c,d)
    !PMAXSD XMM0, XMM2   ; MaxOfAll -> XMM0
    !MOVD EAX, XMM0      ; EAX = Max
    ProcedureReturn      ; Return EAX/RAX
    
  CompilerElse
    
    If a < b : a = b : EndIf
    If a < c : a = c : EndIf
    If a < d : a = d : EndIf
    ProcedureReturn a
    
  CompilerEndIf
  
EndProcedure

CompilerIf #PB_Compiler_64Bit
  #MaxInt = 9223372036854775807
  #MinInt = -9223372036854775808 
CompilerElse
  #MaxInt = 2147483647
  #MinInt = -2147483648 
CompilerEndIf

Procedure Min4i(a, b, c=#MaxInt, d=#MaxInt)
  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
    
    CompilerIf #PB_Compiler_64Bit
      !MOV RAX, [p.v_a]    ; RAX = a
      !CMP RAX, [p.v_b]    ; compare with b
      !CMOVG RAX, [p.v_b]  ; If greater Then Load RAX with b
      !CMP RAX, [p.v_c]    ; compare with c
      !CMOVG RAX, [p.v_c]  ; If greater Then Load RAX with c
      !CMP RAX, [p.v_d]    ; compare with d
      !CMOVG RAX, [p.v_d]  ; If greater Then Load RAX with d
    CompilerElse
      !MOV EAX, [p.v_a]    ; EAX = a
      !CMP EAX, [p.v_b]    ; compare with b
      !CMOVG EAX, [p.v_b]  ; If greater Then Load EAX with b
      !CMP EAX, [p.v_c]    ; compare with c
      !CMOVG EAX, [p.v_c]  ; If greater Then Load EAX with c
      !CMP EAX, [p.v_d]    ; compare with d
      !CMOVG EAX, [p.v_d]  ; If greater Then Load EAX with d
    CompilerEndIf
    
  CompilerElse
    
    If a > b : a = b : EndIf
    If a > c : a = c : EndIf
    If a > d : a = d : EndIf
    ProcedureReturn a
    
  CompilerEndIf
  
  ProcedureReturn      ; Return EAX/RAX
EndProcedure

Procedure Max4i(a, b, c=#MinInt, d=#MinInt)
  
  CompilerIf #PB_Compiler_Backend = #PB_Backend_Asm
    
    CompilerIf #PB_Compiler_64Bit
      !MOV RAX, [p.v_a]    ; RAX = a
      !CMP RAX, [p.v_b]    ; compare with b
      !CMOVL RAX, [p.v_b]  ; If less Then Load RAX with b
      !CMP RAX, [p.v_c]    ; compare with c
      !CMOVL RAX, [p.v_c]  ; If less Then Load RAX with c
      !CMP RAX, [p.v_d]    ; compare with d
      !CMOVL RAX, [p.v_d]  ; If less Then Load RAX with d
    CompilerElse
      !MOV EAX, [p.v_a]    ; EAX = a
      !CMP EAX, [p.v_b]    ; compare with b
      !CMOVL EAX, [p.v_b]  ; If less Then Load EAX with b
      !CMP EAX, [p.v_c]    ; compare with c
      !CMOVL EAX, [p.v_c]  ; If less Then Load EAX with c
      !CMP EAX, [p.v_d]    ; compare with d
      !CMOVL EAX, [p.v_d]  ; If less Then Load EAX with d    
    CompilerEndIf
    ProcedureReturn      ; Return EAX/RAX
    
  CompilerElse
 
    If a < b : a = b : EndIf
    If a < c : a = c : EndIf
    If a < d : a = d : EndIf
    ProcedureReturn a
    
  CompilerEndIf

EndProcedure

Define a=3
Define b=5
Define c=2
Define d=10

Debug Str(a) + ", " + Str(b) + ", " + Str(c) + ", " + Str(d)
Debug ""
Debug "Min of 2 Long = " + Str(Min4l(a,b))
Debug "Max of 2 Long = " + Str(Max4l(a,b))
Debug ""
Debug "Min of 3 Long = " + Str(Min4l(a,b,c))
Debug "Max of 3 Long = " + Str(Max4l(a,b,c))
Debug ""
Debug "Min of 4 Long = " + Str(Min4l(a,b,c,d))
Debug "Max of 4 Long = " + Str(Max4l(a,b,c,d))
Debug ""
Debug "------------------------------"
Debug ""
Debug "Min of 2 Int = " + Str(Min4i(a,b))
Debug "Max of 2 Int = " + Str(Max4i(a,b))
Debug ""
Debug "Min of 3 Int = " + Str(Min4i(a,b,c))
Debug "Max of 3 Int = " + Str(Max4i(a,b,c))
Debug ""
Debug "Min of 4 Int = " + Str(Min4i(a,b,c,d))
Debug "Max of 4 Int = " + Str(Max4i(a,b,c,d))


Re: Simpliest method compare numbers [Resolved]

Posted: Mon Jan 12, 2026 9:56 pm
by AZJIO

Code: Select all

EnableExplicit
Define a, b, c, d, m
a=10
b=2
c=3
d=5

Procedure Max(*a.Integer, *b.Integer)
	If *a\i < *b\i 
		*a\i = *b\i 
	EndIf
EndProcedure

m = a
Max(@m, @b)
Max(@m, @c)
Max(@m, @d)
Debug m
Array

Code: Select all

EnableExplicit
Define Dim a(5)
Define i, m
a(0)=10
a(1)=2
a(2)=3
a(3)=5
a(4)=1
a(5)=4

Procedure Max(*a.Integer, *b.Integer)
	If *a\i < *b\i 
		*a\i = *b\i 
	EndIf
EndProcedure

m = a(0)
For i = 1 To ArraySize(a())
	Max(@m, @a(i))
Next

Debug m
Array

Code: Select all

EnableExplicit
Define Dim a(5)
Define i, m
a(0)=10
a(1)=2
a(2)=3
a(3)=5
a(4)=1
a(5)=4

m = a(0)
For i = 1 To ArraySize(a())
	If m < a(i)
		m = a(i)
	EndIf
Next

Debug m
Array+Procedure

Code: Select all

EnableExplicit
Define Dim a(5)
a(0)=10
a(1)=2
a(2)=3
a(3)=5
a(4)=1
a(5)=4

Procedure Max(Array a(1))
	Protected i, m
	m = a(0)
	For i = 1 To ArraySize(a())
		If m < a(i)
			m = a(i)
		EndIf
	Next
	ProcedureReturn m
EndProcedure

Procedure Min(Array a(1))
	Protected i, m
	m = a(0)
	For i = 1 To ArraySize(a())
		If m > a(i)
			m = a(i)
		EndIf
	Next
	ProcedureReturn m
EndProcedure

Debug Max(a())
Debug Min(a())

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 10:52 pm
by SPH
Mindphazer wrote: Mon Jan 12, 2026 5:55 pm Easier :

Code: Select all

cmb=20

Dim bank(cmb)
For i=1 To cmb
  bank(i)=Random(200)
  Debug bank(i)
Next
Debug "==="
;;;


SortArray(bank(), #PB_Sort_Ascending)
plus_petit=bank(1)


Debug plus_petit

Code: Select all

Debug "= W A I T ="

For boucle=0 To 1
  
cmb=12000000

Dim bank(cmb)
For i=1 To cmb
  bank(i)=Random(200+boucle*1000000000)
Next
;;;
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;

TempsDepart.q = ElapsedMilliseconds()  ; Récupère la valeur actuelle

plus_petit=bank(1)

For i=1 To cmb
  If bank(i)<plus_petit
    plus_petit=bank(i)
  EndIf
Next
;;;

Debug "With this numbers ("+Str(200+boucle*1000000000)+")"
Debug ":"

TempsEcoule.q = ElapsedMilliseconds()-TempsDepart  ; La valeur 'TempsEcoule' devrait être d'environ 1000 millisecondes 

Debug "Code time SPH : "+Str(TempsEcoule)+" ms"

;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;

TempsDepart.q = ElapsedMilliseconds()  ; Récupère la valeur actuelle

SortArray(bank(), #PB_Sort_Ascending)
plus_petit=bank(1)

TempsEcoule.q = ElapsedMilliseconds()-TempsDepart  ; La valeur 'TempsEcoule' devrait être d'environ 1000 millisecondes 

Debug "Code time Mindphazer : "+Str(TempsEcoule)+" ms"

Debug "==="

Next boucle
The speed depends on the size of the numbers being sorted. But your method is very short...

Re: Simpliest method compare numbers [Resolved]

Posted: Mon Jan 12, 2026 11:11 pm
by ChrisR
I wanted to compare the speed between sMaag's min/max macros and my own, which are very similar but using XOR, to see if there was any difference.
Do you have an explanation for the lack of CPU registers? If I can understand it! With XOR, I can chain up to 3 macros in cascade, but only 1 with <= then >

Code: Select all

Macro Min1(a, b)
  (Bool(a < b) * a + Bool(a < b)!1 * b)
EndMacro

Macro Min2(_v1, _v2)
  (_v1*Bool(_v1 <= _v2) + _v2*Bool(_v1 > _v2))
EndMacro
  
a=15 : b=2 : c=10 : d=3 : e=12

Debug Min1(Min1(Min1(a, b), c), d)
;Debug Min1(Min1(Min1(Min1(a, b), c), d), e)   ; Lack of CPU register

Debug Min2(a, b)
;Debug Min2(Min2(a, b), c)                     ; Lack of CPU register 
;Debug Min2(Min2(Min2(a, b), c), d)            ; Lack of CPU register
;Debug Min2(Min2(Min2(Min2(a, b), c), d), e)   ; Lack of CPU register

Re: Simpliest method compare numbers

Posted: Mon Jan 12, 2026 11:47 pm
by Mindphazer
Kwai chang caine wrote: Mon Jan 12, 2026 6:46 pm @Mindphazer
We have the same idea.... :wink:
It's surely a question of climate :lol:
Probably lol
A lot of snow here :mrgreen:

Re: Simpliest method compare numbers

Posted: Tue Jan 13, 2026 12:06 am
by SMaag
NicTheQuick wrote: Mon Jan 12, 2026 5:54 pm Is it always 4 numbers? Or do you want to have a code working for N numbers?
For 4 numbers the easiest solution is that:

Code: Select all

Procedure min4(a, b, c, d)
	Protected min = a
	If b < min: min = b: EndIf
	If c < min: min = c: EndIf
	If d < min: ProcedureReturn d: EndIf
	ProcedureReturn min
EndProcedure

Debug min4(10, 2, 3, 5)
For me that's the simpliest version. If we pack this into a Macro, it works for all Types and it's fast!

Code: Select all

Macro MinOf4(_VarResult, _v1, _v2, _v3, _v4)
  _VarResult = _v1
  If _VarResult > _v2 : _VarResult = _v2 : EndIf
  If _VarResult > _v3 : _VarResult = _v3 : EndIf
  If _VarResult > _v4 : _VarResult = _v4 : EndIf
EndMacro

Macro MaxOf4(_VarResult, _v1, _v2, _v3, _v4)
  _VarResult = _v1
  If _VarResult < _v2 : _VarResult = _v2 : EndIf
  If _VarResult < _v3 : _VarResult = _v3 : EndIf
  If _VarResult < _v4 : _VarResult = _v4 : EndIf
EndMacro

MinOf4(res, 10, 2, 3, 5)
Debug res
MaxOf4(res, 10, 2, 3, 5)
Debug res

Re: Simpliest method compare numbers [Resolved]

Posted: Tue Jan 13, 2026 2:30 am
by skywalk
Use the macro and C back end +optimizer.
For many of course, custom quicksort compare function for numeric array.
For many many, radix sort is fastest.