Incorrect behavior of a comparison

Just starting out? Need help? Post your questions and find answers here.
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Incorrect behavior of a comparison

Post by QuimV »

:o
Anyone have idea why this happens?

Code: Select all

;Code
UVa.f = 5.1
UV.f  = 5
BM.f  = 0.1

Dif.f= (UVa-UV)
If Dif<0
  Dif * (-1)
EndIf

;Incorrect behavior of the comparison
If Dif >= BM
  Debug "major"
EndIf  

;Correct behavior of the comparison
If StrF(Dif,3) >= StrF(BM,3)
  Debug "major"
EndIf  
Thanks in advanced.
QuimV
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

It's all in the rounding of decimal values when stored internally in floating point form.

5.1, when stored as a float value, equates to 5.09999990463257 and thus you can see why your first comparison fails.

Your StrF() comparison is adding additional rounding errors (because you are limiting the number of decimal places) and thus you are getting a positive result this time (a false false positive!)
I may look like a mule, but I'm not a complete ass.
Goos E
New User
New User
Posts: 6
Joined: Sun Mar 15, 2009 2:55 pm
Location: Netherlands

Post by Goos E »

It has something to do with the way a Floating point variable is stored. I am not sure how it works. The example you wrote it shows that the variable UVa = 5.099999990463257 and UV=5.0 so when you subtract UV from UVa the result=0.09999999046325 that is smaller then BM wich is actualy 0.1000000014012.
The use off StrF() is logical becauce it's actualy rounded, wich is for both UVa and BM "0.100"
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Post by QuimV »

so, if I need to make comparations using floats, I should to use the expresion:

If StrF(Dif,3) >= StrF(BM,3)
Debug "major"
EndIf

Is that correct?
QuimV
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Messy and slow!

Relying on a string comparison following additional rounding of the floating point values is not really an ideal solution.

The following results in an incorrect comparison because of the number of decimal places being used by StrF() in this case. A spurious example I know and one that can be countered by using more places of decimals, but it still serves to show how problematic this all is.

Code: Select all

a.f = 1.6500002
b.f = 1.6500001

If StrF(a) > StrF(b)
  Debug "This should be debugged!"
EndIf
What is the exact context of the floating point comparisons? I ask because there may be a better way of proceeding depending on eactly what it is you are trying to achieve? For example, if you are comparing currency values then you stop right there! :)
I may look like a mule, but I'm not a complete ass.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

I got another funny example... o.o/

Code: Select all

a.f = 1.6500000
b.f = 1.6500000

If StrF(a,2) = StrF(b,3)
  Debug "This should be debugged!"
Else
  Debug "But this gets debugged!"
EndIf 
oh... and have a nice day.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Code: Select all

a.f = 1.6500000 
b.f = 1.6500000 

If StrF(a,2) = StrF(b,3) 
  Debug "This should NOT be debugged!" 
Else 
  Debug "But this gets debugged correctly!" 
EndIf 
:wink: :twisted:

You're comparing two strings "1.65" and "1.650" which of course are not equal!
I may look like a mule, but I'm not a complete ass.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

well, I know that....


but I use a value-to-string convesion to eliminate incertaincies of floating-point notation,
and overlook 'by accident' that both conversions use different numbers of decimals....

someone who uses strings to compare floats, and process the conversion somewhere-out-there-in-the-attic
would surely wonder why they are not equal, where the bug is.


.... it's mofo frustrating today that I seem to need to explain each and every lousefart to you... are you having your cycle?
oh... and have a nice day.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Well I was just responding to your 'funny example' so 'scuse me for trying to explain where you had gone wrong!

I don't think anyone who uses strings to compare floats would wonder why StrF(a, 2) and StrF(a, 3) differed?

Whatever............. if you don't want people replying to your posts then don't post!
I may look like a mule, but I'm not a complete ass.
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Post by QuimV »

:D
Just I need to compare currency values.
How could I do that and avoid errors?
Thanks
QuimV
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

First, don't store the currencies as floating point values - no sir! :)

You really want to store your currencies in an exact form. I released a currency library some time ago in the tips and tricks forum. Should be easy enough to find.

**EDIT : http://www.purebasic.fr/english/viewtop ... t=currency
I may look like a mule, but I'm not a complete ass.
QuimV
Enthusiast
Enthusiast
Posts: 337
Joined: Mon May 29, 2006 11:29 am
Location: BARCELONA - SPAIN

Post by QuimV »

:D
srod,
Thanks a lot for your help
QuimV
Post Reply