www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Math float equivalence

reply Lucas Goss <lgoss007 gmail.com> writes:
In many game libraries, they often have some type of float equivalence 
function to work around rounding differences, something like:

float equal(float f1, float f2, epsilon=1e-6)
{
   // check for equivalence between f1 and f2
   // where the difference between them is less than epsilon
}

How does D check for equivalence between floats, does it account for 
rounding errors? If not, is there a library function for this? I noticed 
"math.feqrel" (I still loathe the names of all these functions, I have 
no idea what feqrel is supposed to mean) which seems like it might work, 
but I would think it would take a lot more processing than to just check 
equivalence.

Thanks,
Lucas
Jul 05 2006
next sibling parent reply Oskar Linde <oskar.lindeREM OVEgmail.com> writes:
Lucas Goss skrev:
 In many game libraries, they often have some type of float equivalence 
 function to work around rounding differences, something like:
 
 float equal(float f1, float f2, epsilon=1e-6)
 {
   // check for equivalence between f1 and f2
   // where the difference between them is less than epsilon
 }
 
 How does D check for equivalence between floats, does it account for 
 rounding errors? If not, is there a library function for this? I noticed 
 "math.feqrel" (I still loathe the names of all these functions, I have 
 no idea what feqrel is supposed to mean) which seems like it might work, 
 but I would think it would take a lot more processing than to just check 
 equivalence.

int mfeq(real x, real y, real precision) in std.math seems to be what you are asking for. The bad news is that it is private. The good news is that DMD lets you use it anyway as long as you use the fully qualified name std.math.mfeq. ;) int feqrel(real x, feal y) returns to what precision x and y are equal (number of bits) which may or may not be what you want. feqrel is not the solution to all floating point equivalence, but is a very handy tool in many cases. What is equivalent is really application dependent. Would you consider -1e-99 to be equivalent to 1e-99 for instance? /Oskar
Jul 05 2006
parent Lucas Goss <lgoss007 gmail.com> writes:
Oskar Linde wrote:
 
 int mfeq(real x, real y, real precision)
 
 in std.math seems to be what you are asking for. The bad news is that it 
 is private. The good news is that DMD lets you use it anyway as long as 
 you use the fully qualified name std.math.mfeq. ;)
 

Ah, thanks. But now this has got me asking, why is it private in the first place? And secondly, how can something be private and yet still accessible? I consider using the FQN on a private import to be a broken feature so I'll probably just copy the function to my math library. Thanks again, Lucas
Jul 05 2006
prev sibling parent reply Don Clugston <dac nospam.com.au> writes:
Lucas Goss wrote:
 In many game libraries, they often have some type of float equivalence 
 function to work around rounding differences, something like:
 
 float equal(float f1, float f2, epsilon=1e-6)
 {
   // check for equivalence between f1 and f2
   // where the difference between them is less than epsilon
 }
 
 How does D check for equivalence between floats, does it account for 
 rounding errors? If not, is there a library function for this? I noticed 
 "math.feqrel" (I still loathe the names of all these functions, I have 
 no idea what feqrel is supposed to mean)

It stands for "relative floating point equality". If you have a better name, let me know (I wrote it).
 but I would think it would take a lot more processing than to just check
 equivalence.

Check the source in std.math. It's actually a very fast function (it only has a couple of subtractions and two predictable branches). It's a comparison that exactly captures the precision of IEEE arithmetic. In the Helix library on dsource is a version which is more applicable to games, since it has an absolute difference as well.
Jul 05 2006
parent Lucas Goss <lgoss007 gmail.com> writes:
Don Clugston wrote:
 
 It stands for "relative floating point equality". If you have a better 
 name, let me know (I wrote it).
 
  > but I would think it would take a lot more processing than to just check
  > equivalence.
 
 Check the source in std.math. It's actually a very fast function (it 
 only has a couple of subtractions and two predictable branches).
 It's a comparison that exactly captures the precision of IEEE arithmetic.
 In the Helix library on dsource is a version which is more applicable to 
  games, since it has an absolute difference as well.
 

Ah, I take it you didn't like the name relativeFloatingPointEquality, haha, I guess that's understandable. Maybe something like "relativeEquality" would be nice, but I guess it's as short as possible because that's how mathematicians (I'm partially one) like it? Ever since using the Java and .NET libraries, I now loathe short names because it always seems to be more work to find what you're looking for or to understand something that's unfamiliar. I looked at the std.math code and the feqrel does look pretty fast, I also looked at helix as well. I'll have to see what best fits my need. Thanks, Lucas
Jul 05 2006