Simpliest method compare numbers [Resolved]

Just starting out? Need help? Post your questions and find answers here.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5614
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Simpliest method compare numbers [Resolved]

Post 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
Last edited by Kwai chang caine on Mon Jan 12, 2026 6:47 pm, edited 1 time in total.
ImageThe happiness is a road...
Not a destination

PureBasic French Forum
User avatar
jacdelad
Addict
Addict
Posts: 2062
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Simpliest method compare numbers

Post 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...
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/2*DX517, 164TB+82TB+28TB+2TB SSD
User avatar
SPH
Enthusiast
Enthusiast
Posts: 631
Joined: Tue Jan 04, 2011 6:21 pm

Re: Simpliest method compare numbers

Post 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:

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 6.12LTS - 64 bits
User avatar
NicTheQuick
Addict
Addict
Posts: 1558
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Simpliest method compare numbers

Post 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)
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 526
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: Simpliest method compare numbers

Post 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
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 26.1 - Iphone 17 Pro Max - iPad at home
...and unfortunately... Windows at work...
SMaag
Enthusiast
Enthusiast
Posts: 364
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: Simpliest method compare numbers

Post 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
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5614
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Simpliest method compare numbers

Post 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)
ImageThe happiness is a road...
Not a destination

PureBasic French Forum
User avatar
ChrisR
Addict
Addict
Posts: 1544
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Simpliest method compare numbers [Resolved]

Post 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)
SMaag
Enthusiast
Enthusiast
Posts: 364
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: Simpliest method compare numbers [Resolved]

Post 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))

Last edited by SMaag on Mon Jan 12, 2026 9:58 pm, edited 1 time in total.
AZJIO
Addict
Addict
Posts: 2254
Joined: Sun May 14, 2017 1:48 am

Re: Simpliest method compare numbers [Resolved]

Post 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())
User avatar
SPH
Enthusiast
Enthusiast
Posts: 631
Joined: Tue Jan 04, 2011 6:21 pm

Re: Simpliest method compare numbers

Post 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...

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Portable LENOVO ideapad 110-17ACL 64 bits
Version de PB : 6.12LTS - 64 bits
User avatar
ChrisR
Addict
Addict
Posts: 1544
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: Simpliest method compare numbers [Resolved]

Post 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
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 526
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: Simpliest method compare numbers

Post 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:
MacBook Pro 16" M4 Pro - 24 Gb - MacOS 26.1 - Iphone 17 Pro Max - iPad at home
...and unfortunately... Windows at work...
SMaag
Enthusiast
Enthusiast
Posts: 364
Joined: Sat Jan 14, 2023 6:55 pm
Location: Bavaria/Germany

Re: Simpliest method compare numbers

Post 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
User avatar
skywalk
Addict
Addict
Posts: 4287
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Simpliest method compare numbers [Resolved]

Post 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.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply