如何正确和标准地比较浮点数? [英] How to correctly and standardly compare floats?

查看:20
本文介绍了如何正确和标准地比较浮点数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次我开始一个新项目并且需要比较一些浮点或双精度变量时,我都会编写如下代码:

Every time I start a new project and when I need to compare some float or double variables I write the code like this one:

if (fabs(prev.min[i] - cur->min[i]) < 0.000001 &&
    fabs(prev.max[i] - cur->max[i]) < 0.000001) {
        continue;
}

然后我想摆脱这些神奇的变量 0.000001(和 0.00000000001 对于 double)和 fabs,所以我编写了一个内联函数和一些定义:

Then I want to get rid of these magic variables 0.000001(and 0.00000000001 for double) and fabs, so I write an inline function and some defines:

#define FLOAT_TOL 0.000001

所以我想知道是否有任何标准方法可以做到这一点?可能是一些标准的头文件?有浮动和双重限制(最小值和最大值)也很好

So I wonder if there is any standard way of doing this? May be some standard header file? It would be also nice to have float and double limits(min and max values)

推荐答案

感谢您的回答,他们帮助了我很多.我已经阅读了这些材料:first第二

Thanks for your answers, they helped me a lot. I've read these materials:first and second

答案是使用我自己的函数进行相对比较:

The answer is to use my own function for relative comparison:

bool areEqualRel(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
}

这是最适合我需求的解决方案.但是我写了一些测试和其他比较方法.我希望这对某人有用.areEqualRel 通过了这些测试,其他的则没有.

This is the most suitable solution for my needs. However I've wrote some tests and other comparison methods. I hope this will be useful for somebody. areEqualRel passes these tests, others don't.

#include <iostream>
#include <limits>
#include <algorithm>

using std::cout;
using std::max;

bool areEqualAbs(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon);
}

bool areEqual(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon * std::max(1.0f, std::max(a, b)));
}

bool areEqualRel(float a, float b, float epsilon) {
    return (fabs(a - b) <= epsilon * std::max(fabs(a), fabs(b)));
}

int main(int argc, char *argv[])
{
    cout << "minimum: " << FLT_MIN      << "
";
    cout << "maximum: " << FLT_MAX      << "
";
    cout << "epsilon: " << FLT_EPSILON  << "
";

    float a = 0.0000001f;
    float b = 0.0000002f;
    if (areEqualRel(a, b, FLT_EPSILON)) {
        cout << "are equal a: " << a << " b: " << b << "
";
    }
    a = 1000001.f;
    b = 1000002.f;
    if (areEqualRel(a, b, FLT_EPSILON)) {
        cout << "are equal a: " << a << " b: " << b << "
";
    }
}

这篇关于如何正确和标准地比较浮点数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆