如何有效地检测双重成为NaN的时间?

时间:2015-11-24 23:15:00

标签: java debugging floating-point

我正在开发一个软件,并且在程序的某个时刻,双重成为NaN,它会破坏整个程序。

我可以获得一些关于如何调试这样的问题以及如何找到意外设置为NaN的实际行的帮助吗?

1 个答案:

答案 0 :(得分:2)

缩小向NaN发生的位置有时在执行非常复杂的工作的环境中非常困难。例如,基于物理渲染的作者记录了一个棘手的案例,例如,由于某些表达式评估为NaN而导致计算量过大,因此他的光线跟踪器被放慢到爬行状态。这些东西可能非常棘手,特别是如果它只是一个百万次的边缘情况。

一个方便的技巧是依赖IEEE标准,如果变量值为NaN,则与自身相比的变量将返回false。这可能不适用于所有编译器,因此您可能需要在断言之前确保它已经完成,但是......

boolean is_nan(double val)
{
    return val != val;
}

然而,在Java中我们并不需要这个技巧。我们isNan已经java.lang.Double

通过这种方便,您可以通过执行完整性检查来缩小NaN发生位置,例如:

double val = ...;
// after various arithmetical operations
assert !Double.isNan(val);

然后你可以向下工作(向上?)并通过在遇到断言失败时添加更细粒度的检查来缩小产生NaN的代码行,并注意哪一行代码在哪断言失败了。在非常复杂的情况下,例如引用的光线跟踪器场景,这可能只发生在百万次中,这比尝试通过调试器跟踪所有内容要快得多。