C++ 比较最小值/最大值的浮点数(浮点或双精度)

C++ 比较最小值/最大值的浮点数(浮点或双精度),c++,floating-point,precision,floating-accuracy,C++,Floating Point,Precision,Floating Accuracy,如何比较两个不同的浮动,达到一定的精度。我知道在任何编程语言中使用float或double时都有非常轻微的不精确性,但是这可能足以导致floata我更喜欢的语言是C++。< P>使用 STD::NoimiCiLime::EpSelon()/Cuff>检查两个数字是否相等。如果您想知道一个是否大于/小于,还应考虑相对公差 #include <cmath> #include <limits> template < typename T > bool fuzzy_

如何比较两个不同的浮动,达到一定的精度。我知道在任何编程语言中使用float或double时都有非常轻微的不精确性,但是这可能足以导致float
a
的比较返回一个与实际不同的值

我正在解决一个来自UVa在线法官的问题,他给了我很多次错误的答案。它只使用了很少的浮点值作为输入,但保留了小数点后2位。我想出了一个临时解决方案,就是通过拆分输入并将其转换为int,但我不希望总是这样

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


<> >我更喜欢的语言是C++。

< P>使用<代码> STD::NoimiCiLime::EpSelon()/Cuff>检查两个数字是否相等。如果您想知道一个是否大于/小于,还应考虑相对公差

#include <cmath>
#include <limits>

template < typename T >
bool fuzzy_compare(T a, T b)
{
  return std::abs(a - b) < std::numeric_limits<T>::epsilon();
};
#包括
#包括
模板
布尔模糊比较(TA,TB)
{
返回std::abs(a-b)
只需使用数学:

#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");
}
#定义PREC 0.01/(1/pow(10,n)),n=2
浮点数c=a-b;
如果(abs(c)
使用setprecison()运算符。括号之间的数字将决定输出中包含多少通过小数的数字。请确保包含iomanip库

比较浮点数总是一个棘手的问题,这里有一个更复杂的示例,说明了为什么应该使用
std::numeric\u limits::epsilon()

  • 第一行返回true,但第二行返回false(在我的机器上)

    float64\u t CalculateEpsilon()
    {
    float64\u t l\u AllowedIncuracy=1;//1.1,0.9
    int32_t有效小数位数=2;
    返回(l_允许不准确*功率(0.1,有效小数位数));
    }
    布尔等质量(浮动64_t左侧,浮动64_t右侧)
    {
    float64_t l_Epsilon=CalculateEpsilon();
    浮动64_t l_Delta=std::abs(左侧-右侧);
    
    return l_Delta到目前为止,我还没有经历过由浮点精度引起的错误(我认为问题不会把它推到精度极限)。你的代码在其他任何地方都有点问题。@TatsuyukiIshi我真的不这么认为。我只是将浮点值改为整数,然后将输入拆分为整数,它奇迹般地给出了一个AC结论。:/code>a
    返回它应该返回的结果;它告诉你
    a
    的值是否小于
    的值>b
    (除非你在某个地方有一个NaN,但这不是你要问的)。浮点比较的问题是,你的代码为
    a
    计算的值可能不是你期望的值,因为在计算过程中存在舍入错误。你的示例没有考虑数值限制(顺便说一下,它是C而不是C++解决方案;-):PrtTf,没有命名空间,使用宏)值 EpSelon()/Cuff>是你可以添加到1的最小数量,得到不同的值。当你处理的数字明显大于1时,它实际上是0(因为它在舍入中丢失)。,当你处理明显小于1.0的数字时,它实际上是无限的(因为它比你看到的值大得多,所以你的值在舍入中丢失了)。“近似相等”可能会导致重大问题,因为它是不可传递的。也就是说,如果
    a
    “近似相等”
    b
    b
    “几乎等于”
    c
    ,并不表示
    a
    “几乎等于”
    c
    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;
    }