【发布时间】:2011-06-26 13:51:53
【问题描述】:
我今天花了大约 2 个小时来追踪一个错误,如果将 NaN 与浮点数进行比较,我会发现如果 java 抛出异常会更快。如果我将来能保护自己免受这种情况的影响,那就太好了。任何帮助表示赞赏。
【问题讨论】:
-
听起来你需要一个信号 NaN (SNaN),但我怀疑这是不可能的。
标签: java exception comparison nan
我今天花了大约 2 个小时来追踪一个错误,如果将 NaN 与浮点数进行比较,我会发现如果 java 抛出异常会更快。如果我将来能保护自己免受这种情况的影响,那就太好了。任何帮助表示赞赏。
【问题讨论】:
标签: java exception comparison nan
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。使用的偏差取决于具体情况。
【讨论】:
JVM instruction set reference 明确禁止进行浮点数学运算的字节码抛出异常,并严格指定当 NaN 是操作数时它们应如何工作。如果有办法做到这一点,它要么要求您在 NaN 上显式抛出异常,要么使用自定义编译器为您插入这些检查。
一个可能有用的选项是编写这样的函数:
public static float check(float value) {
if (Float.isNaN(value))
throw new ArithmeticException("NaN");
return value;
}
有了这个,你就可以写出这样的代码了:
float f = check(myOtherFloat / yetAnotherFloat);
这将执行计算并引发错误。理想情况下,使用简短的函数名称不会太突兀。
W
【讨论】: