比较 min/max 的浮点数(浮点数或双精度数)

Comparing floating-point numbers (floats or doubles) for min/max

如何比较两个不同的浮点数,达到一定的准确性。我知道在任何编程语言中使用浮点数或双精度数时都存在非常轻微的不精确性,但这可能足以导致浮点数 a < b 与 return 的比较与实际值不同。

我正在解决 UVa Online Judge 的一个问题,这个问题给了我很多次错误的答案。它采用了很少的浮点值作为输入,尽管是小数点后两位。我找到了临时解决方案,即拆分输入并将其转换为整数,但我不想一直使用它。

所以我的问题是,比较浮点数 a 是否小于(或大于)浮点数 b 的最佳方法是什么,前提是 a 和 b 的输入正确到小数点后 n 位,在这种情况下, 2?

我比较喜欢的语言是C++。

使用std::numeric_limits<T>::epsilon()检查两个数字是否几乎相等。如果你想知道一个是否 greater/less 你还应该考虑相对公差。

#include <cmath>
#include <limits>

template < typename T >
bool fuzzy_compare(T a, T b)
{
  return std::abs(a - b) < std::numeric_limits<T>::epsilon();
};

只需使用数学:

#define PREC 0.01                 //(1/pow(10,n)), n = 2
float c = a-b;
if (abs(c) < PREC) {
    printf("a equals b");
} else if(c < 0){
    printf("b is grater than a");
} else 
    printf("a is grater than b");
}

使用 setprecison() 运算符。您放在括号之间的数字将决定输出中将包含多少通过小数点的数字。请务必包含 iomanip 库。

比较浮点数总是很棘手这里是一个更复杂的例子,说明为什么你应该使用 std::numeric_limits<T>::epsilon().

  • 第一行 returns 正确,但第二行 returns 错误(在我的机器上)。

    float64_t CalculateEpsilon ()
    {
        float64_t l_AllowedInaccuray = 1; // 1.1, 0.9
        int32_t significantDecimalPlaces = 2;
    
        return ( l_AllowedInaccuray * pow ( 0.1, significantDecimalPlaces ) );
    }
    
    bool IsEqual ( float64_t lhs, float64_t rhs )
    {
        float64_t l_Epsilon = CalculateEpsilon ();
    
        float64_t l_Delta = std::abs ( lhs - rhs );
        return l_Delta <= l_Epsilon;
    }
    
    int32_t main ()
    {
        std::cout << IsEqual ( 107.35999999999999, 107.350 );  //returns true
        std::cout << IsEqual ( 107.359999999999999, 107.350 ); //returns false
    
        return 0;
    }