Page 1 of 1

Bug? Float comparision with long

Posted: Sun Oct 15, 2006 8:04 pm
by Trond
Is this a bug?

Code: Select all

; Float cmp Integer
If 1 = 1.4 ; 1 is NOT equal to 1.4 here
  Debug 1
EndIf

a = 1
b.f = 1.4

If a = b ; 1 IS equal to 1.4 here
  Debug 2 ; Only this is shown
EndIf

If b = a ; 1 is NOT equal to 1.4 here
  Debug 3
EndIf

f.f = 1

If f = b ; 1 is NOT equal to 1.4 here
  Debug 4
EndIf

Posted: Mon Oct 16, 2006 12:13 am
by netmaestro
It appears that what's happening is that the rhs is getting cast to the type of the lhs for the comparison. Which would explain the incorrect result happening only when it does. 1.4 dropped into a long becomes 1. Question: How to fix it? Cast everything to doubles for comparisons? That would be accurate for everything except quads but what kind of hit would performance take? Is there a better way?

Posted: Mon Oct 16, 2006 12:43 am
by Rescator
Huge bolded text in manual explaining the LHS RHS behaviour of the casting? :P

PS! Comparing two different types like this is bad coding in a way.
Either manually cast a integer to a float or a float to a integer before comparison.

In the example above I'd advise using Int() around the floats in the comparison, you should then get the (I assume) intended behaviour as per the code.

The behaviour shown in this example is not wrong,
but I do admit it can be a bit confusing.
But it is correct, 1 (aka 1.0) is not equal to 1.4 obviously.

I've never had this issue myself since almost from the start I always made sure to use Int() on floats in the situtation I needed to do integer compares/math.

AFAIK PureBasic will always cast to float if floats are used in a expression.
(isn't this mentioned in the manual even?)

Posted: Mon Oct 16, 2006 12:56 am
by netmaestro
Well, it can't be casting the LHS long to a float in trond's example or it wouldn't be returning a wrong result. It looks like it's treating the LHS type as 'dominant'.

Posted: Mon Oct 16, 2006 1:19 am
by Rescator
Hmm, variable type has higher priority than inline values?
That is kinda odd yeah!

Posted: Mon Oct 16, 2006 6:21 pm
by blueznl
yes and no

it may not explain it totally, but check this:

http://www.xs4all.nl/~bluez/datatalk/pu ... evaluation

Posted: Mon Oct 16, 2006 6:23 pm
by Trond
blueznl wrote:yes and no

it may not explain it totally, but check this:

http://www.xs4all.nl/~bluez/datatalk/pu ... evaluation
But is it intentional? It's a bit crazy that a = b is true while b = a is false.

Posted: Mon Oct 16, 2006 6:33 pm
by Trond
blueznl wrote:yes and no

it may not explain it totally, but check this:

http://www.xs4all.nl/~bluez/datatalk/pu ... evaluation
But is it intentional? It's a bit crazy that a = b is true while b = a is false.
http://www.xs4all.nl/~bluez/datatalk/pure5.htm#1_expression_evaluation wrote:Here a.f turns all into floats, so 10*22+Cos(...) would be processed as a float, finally the result is stored as a float. Note that not only the Cos() itself, but also the parameters of Cos() can force a typechange!

Code:

a.f = Cos(z.f)+10*22
b.f = Cos(z.d)+10*22

In the above the expression behind a.f is evaluated as a float, whilst the one behind b.f is evaluated as a double
That's wrong. The return type of the function causes the type change. It just so happens that the Cos() function returns a float when given a float and returns a double when given a double (it's overloaded). Normal procedure don't act that way.

Posted: Mon Oct 16, 2006 6:33 pm
by blueznl
i admit that's weird, but you're doing something that should never be done anyway, you can NEVER 'equal' a float with anything

inaccuracy in float calculations will always screw up things, so the best one could hope for is:

a.l = 1
b.f = 1

if ( a > b-0.1 ) and ( a < b+0.1 )

haven't tested this though :-)