Float and !=
|
|
rup Eizenberg
Registered User
Join date: 23 May 2008
Posts: 31
|
01-26-2009 08:02
Can someone unstick the plank from my forehead. Why does this create an endless loop? float a=0; float b=1; while(a != b){ a+=0.1; } However this works as intended. float a=0; float b=1; while((string)a != (string)b){ a+=0.1; } its not possible to use comparison with float
|
|
Rolig Loon
Not as dumb as I look
Join date: 22 Mar 2007
Posts: 2,482
|
01-26-2009 08:13
Implicitly typecasting the integers 0 and 1 to floats a and b in your example might be the problem. I'm not in world to test, but try this .... float a=0.0; float b=1.0;
while(a != b){ a+=0.1; }
|
|
rup Eizenberg
Registered User
Join date: 23 May 2008
Posts: 31
|
01-26-2009 08:21
just tried it out. same thing. It is also to note that with the current example (a <= b) works, which unfortunatly doesnt help me really with the project i am on. so far the only thing working for me to "compare not equal" two floats is by using (string) but that doesnt make any sense to me thus far.
|
|
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
|
01-26-2009 08:25
Maybe doing this would show what's wrong.. float a=0.0; float b=1.0;
while (a != b) { llOwnerSay ("a = " + (string)a + ", b = " + (string)b); a+=0.1; }
|
|
Dora Gustafson
Registered User
Join date: 13 Mar 2007
Posts: 779
|
01-26-2009 08:26
Never make a condition based on an exact Equal or Unequal with floating point numbers! Never! Make the program in a way so you can apply <= or >=
_____________________
From Studio Dora
|
|
Sindy Tsure
Will script for shoes
Join date: 18 Sep 2006
Posts: 4,103
|
01-26-2009 08:28
Yeah.. I don't like floats.. They're so.. er.. squishy.
|
|
Day Oh
Registered User
Join date: 3 Feb 2007
Posts: 1,257
|
01-26-2009 08:30
it's not possible to accurately store 0.1 in a float 
|
|
rup Eizenberg
Registered User
Join date: 23 May 2008
Posts: 31
|
01-26-2009 08:44
From: Day Oh it's not possible to accurately store 0.1 in a float  So this is a math problem?
|
|
rup Eizenberg
Registered User
Join date: 23 May 2008
Posts: 31
|
01-26-2009 08:47
From: Dora Gustafson Never make a condition based on an exact Equal or Unequal with floating point numbers! Never! Make the program in a way so you can apply <= or >= i prefere the solution i found by converting with string as it fits better for what i am scripting. Brief example situation: float a; //can be either greater or less then b float b=0.5; to use <= or => i would need two IF clauses one for each condition checking. where as ( (string)a != (string)b ) is a one step deal.
|
|
RobbyRacoon Olmstead
Red warrior is hungry!
Join date: 20 Sep 2006
Posts: 1,821
|
01-26-2009 09:28
From: rup Eizenberg So this is a math problem? It's more of a representation problem, but you seem to get the point. For a really good and short overview of the problem and possible solutions, I would point people to this blog post: Here's an excerpt: From: Christer Ericson I will just note that absolute and relative tolerances are tested as // Absolute tolerance comparison of x and y if (Abs(x – y) <= EPSILON) … and // Relative tolerance comparison of x and y if (Abs(x – y) <= EPSILON * Max(Abs(x), Abs(y)) … The absolute tolerance test fails when x and y become large, and the relative tolerance test fails when they become small. It is therefore desired to combine these two tests together in a single test. Over the years at GDC, as well as in my book, I’ve suggested the following combined tolerance test: if (Abs(x – y) <= EPSILON * Max(1.0f, Abs(x), Abs(y)) … This typically works fine, but Erin Catto pointed out to me that it may sometimes be hard to control the desired behavior with just a single EPSILON that controls both the absolute and the relative tolerance at the same time. When better control is desired we can instead look at the combining of tolerances in the following way. What we are really looking for in terms of equality of x and y is the following combined test: if ((Abs(x - y) <= absTol) || (Abs(x - y) <= relTol * Max(Abs(x), Abs(y)))) … These two expressions can be captured in a single formula as if (Abs(x - y) <= Max(absTol, relTol * Max(Abs(x), Abs(y)))) … or equivalently if (Abs(x - y) <= absTol * Max(1.0f, relTol/absTol * Max(Abs(x), Abs(y)))) …
See the original post for more info.
|
|
rup Eizenberg
Registered User
Join date: 23 May 2008
Posts: 31
|
01-26-2009 10:04
Thank You Robby
that pretty much explains it!
|
|
Pedro McMillan
SLOODLE Developer
Join date: 28 Jul 2007
Posts: 231
|
01-26-2009 10:05
EDIT: doh! Just realised most of this stuff was already mentioned above... should've read before posting! :\
It's worth noting that if the condition "a != b" doesn't work due to floating point representation, then "a < b || a > b" will fail for the same reason, since it is effectively the same thing.
However, if you'll only be dealing with known increments (e.g. of 0.1) then you could use "llAbs(a - b) >= 0.1". It's a bit less efficient, but it will accurately identify if the variables are not the same. You can change the condition operator to "<" if you want to check if they are roughly the same.
That kind of technique is used quite a bit in physical modelling for games, especially on platforms which don't support floating-point operations (although there's practically none of them any more). They would use fixed-point instead, storing and processing everything as integers, which is a lot faster, but numerically far less accurate (e.g. every number could quite easily be +/- 0.125, depending on the precision decided-upon, but for platforms like mobile (cell) phones, that's usually enough accuracy).
|