我有一组值 a[i]。
然后我计算
for(...){
b[i] = log(a[i]);
}
Run Code Online (Sandbox Code Playgroud)
然后我总结
for(...){
s += c[i] * b[i];
}
Run Code Online (Sandbox Code Playgroud)
到目前为止这没有问题。
但对于某些人来说,i我a[i]可能为零并导致b[i] = log(0) = -Inf. 对于这些i,c[i]也为零 - 这些是一些无效的数据点。但zero*-Inf似乎给了NaN,我的总和搞砸了......
有没有办法c[i] * b[i]在c[i]is = 0时总是有= 0?
我看到的唯一方法是将所有零设置a[i]为一个小的非零值或检查零,但可能有更好的解决方案。
我使用 C++ 和std数学函数,但我正在寻找一种尽可能通用的方法。
简而言之:
for(...){
double tmp = c[i] * b[i];
s += (tmp == tmp) ? tmp : 0;
}
Run Code Online (Sandbox Code Playgroud)
0 * Inf 是 NaN通过定义(IEEE 754标准) -所以你不能改变这种行为。
测试数字是否为 nan 的“教科书”方式是与自身进行比较,例如:
if (x != x)
std::cout << "x is nan" << std::endl;
else
std::cout << "x is not nan" << std::endl;
Run Code Online (Sandbox Code Playgroud)
这取决于这样一个事实 NaN不等于任何事物,包括它自身。(再次根据定义)。
C++11 引入了is_nan,它更具可读性,如果你没有 C++11,我建议你自己写
bool isnan(double arg) { return arg != arg; }
Run Code Online (Sandbox Code Playgroud)
事实上,NaN与任何事情都没有比较,所以以下都有效:
if (x < y) std::cout << "x is not nan" << std::endl;
if (x > y) std::cout << "x is not nan" << std::endl;
if (x <= y) std::cout << "x is not nan" << std::endl;
if (x >= y) std::cout << "x is not nan" << std::endl;
Run Code Online (Sandbox Code Playgroud)
这种令人惊讶的行为背后的原因(请参阅此问题)是能够使用上述条件进行编码以过滤掉NaN代码,这使得代码非常简单,并且还NaN为not set或unknown值提供了合适的哨兵。
| 归档时间: |
|
| 查看次数: |
5092 次 |
| 最近记录: |