Skip to content

Commit e337a1a

Browse files
authored
Added comparison functions for floats and doubles… (#2321)
* 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 <paulhoux@users.noreply.github.com>
1 parent 4e27a4a commit e337a1a

File tree

1 file changed

+67
-1
lines changed

1 file changed

+67
-1
lines changed

include/cinder/CinderMath.h

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,75 @@ struct CI_API math<float>
123123
#define M_PI 3.14159265358979323846
124124
#endif
125125

126-
const double EPSILON_VALUE = 4.37114e-05;
126+
constexpr double EPSILON_VALUE = 4.37114e-05;
127127
#define EPSILON EPSILON_VALUE
128128

129+
CI_API inline bool approxZero( float n, float epsilon = float(EPSILON_VALUE) )
130+
{
131+
return std::abs( n ) < epsilon;
132+
}
133+
134+
CI_API inline bool approxZero( double n, double epsilon = EPSILON_VALUE )
135+
{
136+
return std::abs( n ) < epsilon;
137+
}
138+
139+
CI_API inline float roundToZero( float n, float epsilon = float(EPSILON_VALUE) )
140+
{
141+
return approxZero( n, epsilon ) ? 0.0f : n;
142+
}
143+
144+
CI_API inline double roundToZero( double n, double epsilon = EPSILON_VALUE )
145+
{
146+
return approxZero( n, epsilon ) ? 0.0 : n;
147+
}
148+
149+
CI_API inline bool approxEqual( float a, float b, float epsilon = float(EPSILON_VALUE) )
150+
{
151+
return std::abs( b - a ) < epsilon;
152+
}
153+
154+
CI_API inline bool approxEqual( double a, double b, double epsilon = EPSILON_VALUE )
155+
{
156+
return std::abs( b - a ) < epsilon;
157+
}
158+
159+
CI_API inline bool approxEqualRelative( float a, float b, float maxRelDiff = float(EPSILON_VALUE) )
160+
{
161+
// See: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
162+
163+
// Calculate the difference.
164+
const float diff = std::abs( a - b );
165+
166+
// Find the largest.
167+
a = std::abs( a );
168+
b = std::abs( b );
169+
const float largest = ( b > a ) ? b : a;
170+
171+
if( diff <= largest * maxRelDiff )
172+
return true;
173+
174+
return false;
175+
}
176+
177+
CI_API inline bool approxEqualRelative( double a, double b, double maxRelDiff = EPSILON_VALUE )
178+
{
179+
// See: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
180+
181+
// Calculate the difference.
182+
const double diff = std::abs( a - b );
183+
184+
// Find the largest.
185+
a = std::abs( a );
186+
b = std::abs( b );
187+
const double largest = ( b > a ) ? b : a;
188+
189+
if( diff <= largest * maxRelDiff )
190+
return true;
191+
192+
return false;
193+
}
194+
129195
inline float toRadians( float x )
130196
{
131197
return x * 0.017453292519943295769f; // ( x * PI / 180 )

0 commit comments

Comments
 (0)