78 lines
1.7 KiB
C++
78 lines
1.7 KiB
C++
#include <myx/math/float_cmp_types.hpp>
|
|
#include <myx/math/almost_equal_ulps_and_abs.hpp>
|
|
|
|
#include <cmath>
|
|
|
|
namespace myx {
|
|
|
|
namespace math {
|
|
|
|
bool almost_equal_ulps_and_abs( const float a, const float b,
|
|
const float maxAbsDiff, const int maxUlpsDiff )
|
|
{
|
|
// Check if the numbers are really close -- needed
|
|
// when comparing numbers near zero.
|
|
float absDiff = fabsf( a - b );
|
|
if ( absDiff <= maxAbsDiff )
|
|
{
|
|
return( true );
|
|
}
|
|
|
|
float_cmp_t uA( a );
|
|
float_cmp_t uB( b );
|
|
|
|
// Different signs means they do not match.
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
|
if ( uA.negative() != uB.negative() )
|
|
{
|
|
return( false );
|
|
}
|
|
|
|
// Find the difference in ULPs.
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
|
int ulpsDiff = std::abs( uA.i - uB.i );
|
|
if ( ulpsDiff <= maxUlpsDiff )
|
|
{
|
|
return( true );
|
|
}
|
|
|
|
return( false );
|
|
} // almost_equal_ulps_and_abs
|
|
|
|
|
|
bool almost_equal_ulps_and_abs( const double a, const double b,
|
|
const double maxAbsDiff, const int maxUlpsDiff )
|
|
{
|
|
// Check if the numbers are really close -- needed
|
|
// when comparing numbers near zero.
|
|
double absDiff = fabs( a - b );
|
|
if ( absDiff <= maxAbsDiff )
|
|
{
|
|
return( true );
|
|
}
|
|
|
|
double_cmp_t uA( a );
|
|
double_cmp_t uB( b );
|
|
|
|
// Different signs means they do not match.
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
|
if ( uA.negative() != uB.negative() )
|
|
{
|
|
return( false );
|
|
}
|
|
|
|
// Find the difference in ULPs.
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-union-access)
|
|
auto ulpsDiff = std::abs( uA.i - uB.i );
|
|
if ( ulpsDiff <= maxUlpsDiff )
|
|
{
|
|
return( true );
|
|
}
|
|
|
|
return( false );
|
|
} // almost_equal_ulps_and_abs
|
|
|
|
} // namespace math
|
|
|
|
} // namespace myx
|