gpt4 book ai didi

c++ - 添加两个对数时防止下溢

转载 作者:太空狗 更新时间:2023-10-29 22:59:17 25 4
gpt4 key购买 nike

我正在使用维基百科上描述的对数空间方程中的加法 log probability文章,但是在计算非常大的负对数的 exp 时,我遇到了下溢。结果,我的程序崩溃了。

示例输入是 a = -2b = -1033.4391885529124

我的代码直接从维基百科文章中实现,如下所示:

double log_sum(double a, double b)
{
double min_ab = std::min(a, b);
a = std::max(a, b);
b = min_ab;
if (isinf(a) && isinf(b)) {
return -std::numeric_limits<double>::infinity();
} else if (isinf(a)) {
return b;
} else if (isinf(b)) {
return a;
} else {
return a + log2(1 + exp2(b - a));
}
}

我想到了以下想法,但无法决定哪个是最好的:

  • 在评估之前检查是否有超出范围的输入。
  • (以某种方式)禁用异常,并在评估后刷新或钳制输出
  • 实现自定义日志和 exp 函数,这些函数不会抛出异常并自动刷新或限制结果。
  • 其他方式?

此外,我很想知道选择对数底对计算有何影响。我选择基数二是因为我认为其他对数基数将根据 log_n(x) = log_2(x)/log_2(n) 计算,并且会因除法而遭受精度损失。对吗?

最佳答案

根据 http://en.cppreference.com/w/cpp/numeric/math/exp :

For IEEE-compatible type double, overflow is guaranteed if 709.8 < arg, and underflow is guaranteed if arg < -708.4

所以你无法阻止下溢。然而:

If a range error occurs due to underflow, the correct result (after rounding) is returned.

所以不应该有任何程序崩溃 - “只是”精度损失。

但是,请注意

1 + exp(n)

会更快地失去精度,即已经在 n = -53。这是因为 1.0 之后的下一个可表示数字是 1.0 + 2^-52

因此 exp 造成的精度损失远小于添加 1.0 + exp(...) 时的精度损失

关于c++ - 添加两个对数时防止下溢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37390536/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com