Comparing Floats for Equality or Inequality
|
Jeri Zuma
Registered User
Join date: 28 Jun 2004
Posts: 77
|
11-21-2004 12:47
I ran into a problem with floats (as a relatively new coder) that I thought should not be happening... I was using simple float addition to increment a scaling value... e.g. 2.5 + .01 .... and then finally comparing the repeat additions against a maximum value... say, 3.0 .. What I found out is that in even simple float addition, 2.5 +0.1 +0.1+.01+0.1+.01 does not always equal 3.0. Even heeding the warning against using a boolian == or != to compare 2 floats, I thought that 2.5 +0.1 +0.1+.01+0.1+.01 should reliably equal 3.0, and tried just using == or != ... What I learned is that there is float creep in the LSL math engine, so that the sum frequently results in 2.9999999997. Thus the truism that you can't just do equality or inequality float comparisons in LSL is very real. I ended up using the following functions for all the times that I needed to do a == or != with floats, with good results. The precision of .01 was sufficient for my project... you may need to adjust the precision as the needs of your project dictate.
integer floatCompareEqual(float firstNumber, float secondNumber) { integer retval; if ( llFabs(firstNumber - secondNumber) < .01 ) { retval = TRUE; } else { retval = FALSE; } return retval; } integer floatCompareUnequal(float firstNumber, float secondNumber) { integer retval; if ( llFabs(firstNumber - secondNumber) > .01 ) { retval = TRUE; } else { retval = FALSE; } return retval;
|
blaze Spinnaker
1/2 Serious
Join date: 12 Aug 2004
Posts: 5,898
|
11-21-2004 14:42
I'm not aware of another programming language that doesn't suffer from this problem.
_____________________
Taken from The last paragraph on pg. 16 of Cory Ondrejka's paper " Changing Realities: User Creation, Communication, and Innovation in Digital Worlds : " User-created content takes the idea of leveraging player opinions a step further by allowing them to effectively prototype new ideas and features. Developers can then measure which new concepts most improve the products and incorporate them into the game in future patches."
|
Azelda Garcia
Azelda Garcia
Join date: 3 Nov 2003
Posts: 819
|
11-21-2004 15:01
This is not an issue with the way floats are implemented in LSL, this is a direct result of what a float is. Whilst occasionally we do need to resort to doing things like llFabs( value1 - value2 ) < fArbitraryCutoff (more so for vectors actually), usually its sufficient to do a simple one-way comparison. The other way of handling it is to put your iterator in an integer and just multiply by your iterative interval: integer i; for( i = 0; i <= 6; i++ ) { float fMyFloat = (float)i * 0.5; }
Azelda
|
Jeri Zuma
Registered User
Join date: 28 Jun 2004
Posts: 77
|
Thank you ...
11-21-2004 17:49
... for the enlightening replies! Apparently, until now, I never did much coding with floats, and I understand that its not unique to LSL.... However, you must admit that there is something funny about 2.0 + 2.0 equalling 3.999999998 when you'd think that getting it to 4.0 shouldnt be such a big deal! Btw, (as a newbie poster especially), how do you get the code snippets into the nice code box? 
|
Azelda Garcia
Azelda Garcia
Join date: 3 Nov 2003
Posts: 819
|
11-21-2004 21:34
The word code within square-brackets at the start and /code in square brackets at the end.
|
Issarlk Chatnoir
Cross L. apologist.
Join date: 3 Oct 2004
Posts: 424
|
11-22-2004 00:40
I would be very surprised if floats behaved like this in other languages. If you add a very small number to a very large one I understand it will do nothing; but 2.5 + 0.1 ? It sounds ridiculous.
_____________________
Vincit omnia Chaos From: Flugelhorn McHenry Anyway, ignore me, just listen to the cow
|
Adam Zaius
Deus
Join date: 9 Jan 2004
Posts: 1,483
|
11-22-2004 00:54
From: Issarlk Chatnoir I would be very surprised if floats behaved like this in other languages. If you add a very small number to a very large one I understand it will do nothing; but 2.5 + 0.1 ? It sounds ridiculous. All major programming languages have this; it's due to the way floats are represented internally, floats are an approximation rather than a actual value. You will find that they will often be 2^-24 off. -Adam
|
Alexander Daguerre
Junior Birdman
Join date: 9 Jun 2004
Posts: 32
|
11-22-2004 01:46
From: Jeri Zuma However, you must admit that there is something funny about 2.0 + 2.0 equalling 3.999999998 when you'd think that getting it to 4.0 shouldnt be such a big deal! Actually, I think you'll find that if you actually compute 2.0 + 2.0 you will get exactly 4.0, as all of these numbers can be represented exactly by the machine. The problem is that 0.1 can't be represented exactly, so that adding 0.1 twenty times isn't necessarily the same as adding 2.0. In general, if you write code that performs equality comparisons (==, !=) on floating point values, it will turn round and bite you one day, so it is best to find another way to express the functionality (like Azelda's solution, or your own). In LSL, this applies to vector and rotation data as well as float data.
|
Jeri Zuma
Registered User
Join date: 28 Jun 2004
Posts: 77
|
Thank you again ....
11-22-2004 16:10
... your posts have cleared up all of my confusion on this issue. thank_you() { llSay(0,"Thank you!" + " :) " ); }
- Jeri
|