5

我今天花了大约 2 个小时来追踪一个错误,我会发现在将 NaN 与浮点数进行比较时,如果 java 抛出异常会更快。如果我将来能保护自己免受这种情况的影响,那就太好了。任何帮助表示赞赏。

4

2 回答 2

5

JVM 指令集参考明确禁止进行浮点数学运算的字节码抛出异常,并严格指定当 NaN 是操作数时它们应如何工作。如果有办法做到这一点,它要么要求您在 NaN 上显式抛出异常,要么使用自定义编译器为您插入这些检查。

一个可能有用的选项是编写这样的函数:

public static float check(float value) {
    if (Float.isNaN(value))
        throw new ArithmeticException("NaN");
    return value;
}

有了这个,您可以编写代码来实现这种效果:

float f = check(myOtherFloat / yetAnotherFloat);

然后这将进行计算并引发错误。理想情况下,使用简短的函数名称不会太突兀。

W

于 2011-02-13T20:33:05.643 回答
2

float 或 double 中的保护是使结果为 NaN 或 false。如果要检测 NaN,最好首先防止该值,例如 0/0。当你进行除法时,检查 0 作为除数,如果是则抛出异常。您可以使用辅助方法包装它以简化。

public static double div(double a, double b) {
    if(b == 0) throw new IllegalArguementException();
    return a / b;
}

如果我知道该值只能为 0 或更大,我经常添加一个偏差,例如

double d = a / (b + 1e-9);

如果 b >= 0,这永远不会产生 NaN。如果 a == 0,d == 0。使用的偏差取决于情况。

于 2011-02-13T20:32:46.770 回答