【发布时间】:2011-03-12 09:20:22
【问题描述】:
我正在开展一个项目,该项目基于这些查询的结果进行大量查询和一些数学建模,最后是一些评分(阅读:“执行时间太长,无法彻底测试”)。
最近我在我的代码中发现了一个相当新的问题/错误;一些结果得到NaN 的分数值!以下是分数的计算方式:
请注意,pfound、psig 是 doubles,始终为正或 0
Double score1 = (pfound!=0) ? (Math.log(factorial((int)psig + 1))/pfound) : 0;
score1 = score1 * alpha_coeff[0];
if (score1.isInfinite())
throw new RuntimeException(p.getName() + " score1 = Inf");
else if(score1.isNaN())
throw new RuntimeException(p.getName() + " score1 = NaN");
我已经检查了触发 NaN 的可能原因,但我相信大多数情况下它应该是安全的:
我已经在检查 pfound == 0(所以没有除以零)
Math.log() 的参数不能为负值
我怀疑factorial()(将阶乘返回为long 的自定义函数)是否返回long 大到不能在不损失精度的情况下转换为double或类似的东西。我检查了Long.doubleValue(),如果它的参数导致NaN,显然它会生成NaN。
有没有cmets?我在这里错过了一些基本的东西吗?
【问题讨论】:
-
不要担心将 long 转换为 double - 从某种意义上说,这始终是安全的,因为它不会产生 NaN,尽管您可能会丢失一些低阶精度。