当使用Java进行浮点数比较时,如果其中一个是NaN,我能否让它抛出异常?

5

今天我花了大约2个小时追踪一个bug,如果Java在比较NaN与float时抛出异常,我会更快地找到它。希望能够在未来避免此类问题。 感谢任何帮助。


1
听起来你需要一个信号NaN(SNaN),但我怀疑这是不可能的。 - Gabe
事实上,Java不支持信号比较 - Jouni K. Seppänen
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);

这样做将会进行计算并抛出一个错误。如果函数名简短,那么它就不会太显眼。

2

在float或double中的保护是使结果变成NaN或false。如果您想检测NaN,最好预先防止值出现,例如0/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。使用的偏置取决于情况。

我喜欢这个想法,但是无穷大乘以零怎么办?在乘法中你会做同样的事情吗? - templatetypedef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接