Horde3D
http://www.horde3d.org/forums/

Vec3f operator== problem
http://www.horde3d.org/forums/viewtopic.php?f=3&t=1887
Page 1 of 1

Author:  attila [ 23.05.2013, 08:06 ]
Post subject:  Vec3f operator== problem

We found this bug when migrated our engine and tools to Visual Studio 2012.
Our geo files are 50%-200% larger after converting with the new ColladaConv.
The vertices are duplicated for each index. The problem is with Vec3f operator==

Code:
   bool operator==( const Vec3f &v ) const
   {
      return (x > v.x - Math::Epsilon && x < v.x + Math::Epsilon &&
              y > v.y - Math::Epsilon && y < v.y + Math::Epsilon &&
              z > v.z - Math::Epsilon && z < v.z + Math::Epsilon);
   }

For sufficiently large numbers "x - Math::Epsilon" or "x + Math::Epsilon" has exactly the same bit representation as "x" because the mantissa/significand is not large enough to represent the small change. In this case this function returns false even if this' value was exactly the same as v's value.

The difference between VS2008 and VS2012 is that the new version uses sse instructions while the old used standard floating point instructions.

I think the correct version should be:
Code:
   bool operator==( const Vec3f &v ) const
   {
      return (x >= v.x - Math::Epsilon && x <= v.x + Math::Epsilon &&
              y >= v.y - Math::Epsilon && y <= v.y + Math::Epsilon &&
              z >= v.z - Math::Epsilon && z <= v.z + Math::Epsilon);
   }


It also makes sense as the operator== and operator!= should satisfy that !(a==b) == (a!=b).

Author:  Siavash [ 24.05.2013, 12:59 ]
Post subject:  Re: Vec3f operator== problem

I think problem stems from SSE units being less accurate than FPU on some architectures. No idea about MSVC 2012, but on 64bit builds MSVC (2010) automatically enables SSE/SSE2 optimizations and uses scaler SSE instructions and XMM registers (Don't expect any noticeable speed up). Can you try this one too please? This generates smaller code :)
Code:
// Shouldn't Math::ZeroEpsilon instead being used here?

bool operator==( const Vec3f &v ) const
{
   return (fabsf(x - v.x) <= Math::Epsilon &&
      fabsf(y - v.y) <= Math::Epsilon &&
      fabsf(z - v.z) <= Math::Epsilon);
}


EDIT: Changes are available at fastmath branch, commit 341318be15.

Author:  Volker [ 24.05.2013, 18:19 ]
Post subject:  Re: Vec3f operator== problem

Floating point comparing always sucks, as the preferable precision of comparison depends on the usage context most of the time.

There is also some code provided in the google test code provided here:
http://code.google.com/p/googletest/sou ... internal.h
and some nice information here:
http://www.cygnus-software.com/papers/c ... floats.htm

If we found a solution that fits most of the test cases in a proper way (under VS2012 as well as under other compilers) I will commit that solution to the SVN.

Author:  attila [ 24.05.2013, 19:04 ]
Post subject:  Re: Vec3f operator== problem

Siavash wrote:
I think problem stems from SSE units being less accurate than FPU on some architectures. No idea about MSVC 2012, but on 64bit builds MSVC (2010) automatically enables SSE/SSE2 optimizations and uses scaler SSE instructions and XMM registers (Don't expect any noticeable speed up). Can you try this one too please? This generates smaller code :)
Code:
// Shouldn't Math::ZeroEpsilon instead being used here?

bool operator==( const Vec3f &v ) const
{
   return (fabsf(x - v.x) <= Math::Epsilon &&
      fabsf(y - v.y) <= Math::Epsilon &&
      fabsf(z - v.z) <= Math::Epsilon);
}




It looks ok to me(same as "Comparing with epsilon – absolute error" in the doc attached by Volker), I will try on Monday at work. Also probably faster(if fabsf is implemented inline without a function call) as there are less branches.

Volker wrote:
Floating point comparing always sucks, as the preferable precision of comparison depends on the usage context most of the time.

There is also some code provided in the google test code provided here:
http://code.google.com/p/googletest/sou ... internal.h
and some nice information here:
http://www.cygnus-software.com/papers/c ... floats.htm

If we found a solution that fits most of the test cases in a proper way (under VS2012 as well as under other compilers) I will commit that solution to the SVN.


Relative error comparisons seems complicated, I would choose Siavash's version.

Author:  swx [ 29.05.2013, 11:34 ]
Post subject:  Re: Vec3f operator== problem

IMO operator== should only check for exactly the same values. It is better to provide another function that uses epsilon comparison.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/