我正在开发一个软件,并且在程序的某个时刻,双重成为NaN,它会破坏整个程序。
我可以获得一些关于如何调试这样的问题以及如何找到意外设置为NaN的实际行的帮助吗?
答案 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的代码行,并注意哪一行代码在哪断言失败了。在非常复杂的情况下,例如引用的光线跟踪器场景,这可能只发生在百万次中,这比尝试通过调试器跟踪所有内容要快得多。