Skip to content

Commit

Permalink
Added comparison functions for floats and doubles… (#2321)
Browse files Browse the repository at this point in the history
* Added comparison functions for floats and doubles, providing a safer way to do things like `double value; if( value == 0.0 ){}`.

* Added approxEqualRelative() functions and removed the custom epsilon in favor of FLT_EPSILON and DBL_EPSILON.

authored-by: paulhoux <[email protected]>
  • Loading branch information
paulhoux authored Dec 31, 2023
1 parent 4e27a4a commit e337a1a
Showing 1 changed file with 67 additions and 1 deletion.
68 changes: 67 additions & 1 deletion include/cinder/CinderMath.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,75 @@ struct CI_API math<float>
#define M_PI 3.14159265358979323846
#endif

const double EPSILON_VALUE = 4.37114e-05;
constexpr double EPSILON_VALUE = 4.37114e-05;
#define EPSILON EPSILON_VALUE

CI_API inline bool approxZero( float n, float epsilon = float(EPSILON_VALUE) )
{
return std::abs( n ) < epsilon;
}

CI_API inline bool approxZero( double n, double epsilon = EPSILON_VALUE )
{
return std::abs( n ) < epsilon;
}

CI_API inline float roundToZero( float n, float epsilon = float(EPSILON_VALUE) )
{
return approxZero( n, epsilon ) ? 0.0f : n;
}

CI_API inline double roundToZero( double n, double epsilon = EPSILON_VALUE )
{
return approxZero( n, epsilon ) ? 0.0 : n;
}

CI_API inline bool approxEqual( float a, float b, float epsilon = float(EPSILON_VALUE) )
{
return std::abs( b - a ) < epsilon;
}

CI_API inline bool approxEqual( double a, double b, double epsilon = EPSILON_VALUE )
{
return std::abs( b - a ) < epsilon;
}

CI_API inline bool approxEqualRelative( float a, float b, float maxRelDiff = float(EPSILON_VALUE) )
{
// See: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

// Calculate the difference.
const float diff = std::abs( a - b );

// Find the largest.
a = std::abs( a );
b = std::abs( b );
const float largest = ( b > a ) ? b : a;

if( diff <= largest * maxRelDiff )
return true;

return false;
}

CI_API inline bool approxEqualRelative( double a, double b, double maxRelDiff = EPSILON_VALUE )
{
// See: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/

// Calculate the difference.
const double diff = std::abs( a - b );

// Find the largest.
a = std::abs( a );
b = std::abs( b );
const double largest = ( b > a ) ? b : a;

if( diff <= largest * maxRelDiff )
return true;

return false;
}

inline float toRadians( float x )
{
return x * 0.017453292519943295769f; // ( x * PI / 180 )
Expand Down

0 comments on commit e337a1a

Please sign in to comment.