#include #include #include namespace myx { namespace math { bool almost_equal_ulps( const float a, const float b, const int maxUlpsDiff ) { float_cmp_t uA( a ); float_cmp_t uB( b ); // Если знаки разные, то числа не равны. if ( uA.negative() != uB.negative() ) { // Кроме случая, когда +0==-0 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif if ( a == b ) #ifdef __GNUC__ #pragma GCC diagnostic pop #endif { return( true ); } return( false ); } // Разница в младших битах. auto ulpsDiff = std::abs( uA.i - uB.i ); if ( ulpsDiff <= maxUlpsDiff ) { return( true ); } return( false ); } // almost_equal_ulps bool almost_equal_ulps( const double a, const double b, const int maxUlpsDiff ) { double_cmp_t uA( a ); double_cmp_t uB( b ); // Если знаки разные, то числа не равны. if ( uA.negative() != uB.negative() ) { // Кроме случая, когда +0==-0 #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wfloat-equal" #endif if ( a == b ) #ifdef __GNUC__ #pragma GCC diagnostic pop #endif { return( true ); } return( false ); } // Разница в младших битах. auto ulpsDiff = std::abs( uA.i - uB.i ); if ( ulpsDiff <= maxUlpsDiff ) { return( true ); } return( false ); } // almost_equal_ulps } // namespace math } // namespace myx