为了账号安全,请及时绑定邮箱和手机立即绑定

如何做浮点比较?

如何做浮点比较?

如何做浮点比较?我目前正在编写一些代码,其中有如下内容:double a = SomeCalculation1();double b = SomeCalculation2();if (a < b)     DoSomething2();else if (a > b)     DoSomething3();然后在其他地方,我可能需要做平等:double a = SomeCalculation3();double b = SomeCalculation4();if (a == 0.0)    DoSomethingUseful(1 / a);if (b == 0.0)    return 0; // or something else here总之,我有很多浮点的数学,我需要做各种条件的比较。我不能把它转换成整数数学,因为在这个上下文中,这样的事情是没有意义的。我以前读过浮点比较可能是不可靠的,因为您可以这样做:double a = 1.0 / 3.0;double b = a + a + a;if ((3 * a) != b)     Console.WriteLine("Oh no!");简而言之,我想知道:如何可靠地比较浮点数(小于,大于等于)?我使用的数字范围大概在10e-14到10E6之间,所以我确实需要处理小数字和大数字。我将此标记为语言不可知论者,因为无论我使用哪种语言,我都对如何实现这一目标感兴趣。
查看完整描述

3 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

比较更大/更小并不是一个真正的问题,除非你在浮动/双精度限制的边缘工作。

对于一个“模糊等于”的比较,这个(Java代码,应该很容易适应)是我想出来的浮点指南经过大量的工作,并考虑到了大量的批评:

public static boolean nearlyEqual(float a, float b, float epsilon) {
    final float absA = Math.abs(a);
    final float absB = Math.abs(b);
    final float diff = Math.abs(a - b);

    if (a == b) { // shortcut, handles infinities
        return true;
    } else if (a == 0 || b == 0 || diff < Float.MIN_NORMAL) {
        // a or b is zero or both are extremely close to it
        // relative error is less meaningful here
        return diff < (epsilon * Float.MIN_NORMAL);
    } else { // use relative error
        return diff / (absA + absB) < epsilon;
    }}

它附带了一个测试套件。您应该立即排除任何没有的解决方案,因为在某些边缘情况下,几乎可以保证它会失败,比如有一个值0,两个与零相对的非常小的值,或者无穷大值。

另一种选择(更多细节请参见上面的链接)是将浮点数的位模式转换为整数,并接受固定整数距离内的所有内容。

在任何情况下,可能没有任何解决方案是完美的所有应用程序。理想情况下,您应该使用包含实际用例的测试套件来开发/调整自己的应用程序。


查看完整回答
反对 回复 2019-06-19
?
月关宝盒

TA贡献1772条经验 获得超5个赞

我有个比较浮点数的问题A < BA > B以下是似乎行之有效的方法:

if(A - B < Epsilon) && (fabs(A-B) > Epsilon){
    printf("A is less than B");}if (A - B > Epsilon) && (fabs(A-B) > Epsilon){
    printf("A is greater than B");}

晶圆厂-绝对值-照顾到它们是否本质上是平等的。


查看完整回答
反对 回复 2019-06-19
?
MM们

TA贡献1886条经验 获得超2个赞

我们必须选择一个公差级别来比较浮点数。例如,

final float TOLERANCE = 0.00001;if (Math.abs(f1 - f2) < TOLERANCE)
    Console.WriteLine("Oh yes!");

一个音符。你的例子很有趣。

double a = 1.0 / 3.0;double b = a + a + a;if (a != b)
    Console.WriteLine("Oh no!");

这里有些数学

a = 1/3b = 1/3 + 1/3 + 1/3 = 1.1/3 != 1

哦,是的.。

你是说

if (b != 1)
    Console.WriteLine("Oh no!")


查看完整回答
反对 回复 2019-06-19
  • 3 回答
  • 0 关注
  • 561 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信