c++ - C++ 指数分布偶尔会返回预期为 0 的 inf
问题描述
在一个项目中,我正在生成数百万个 expo(lambda) 随机变量,其中 lambda 可能非常大。使用时,std::exponential_distribution<float>
我偶尔会得到一个返回值inf
。如果 lambda 接近 0,我会理解这一点,但是当 lambda 很大时,预期值非常接近于零。例如,以下程序通常在几百万次抽奖后终止:
#include<iostream>
#include<random>
int main(void)
{
std::random_device rd;
std::mt19937 generator(rd());
float lambda = 1000000.0;
float val = 0;
for(int i = 0; i < 1000000000; ++i)
{
std::exponential_distribution<float> dist(lambda);
val = dist(generator);
if(isinf(val))
{
std::cout << i << " " << val << " failure" << std::endl;
exit(0);
}
}
return 0;
}
如果函数中有一些错误(由于精度),为什么它返回inf
而不是更方便0.0
?除了手动检查输出是否有限之外,还有什么方法可以解决这个问题?谢谢。
解决方案
理查德克里顿的评论说:
“......如果 RealType 是浮点数,某些实现可能偶尔会返回无穷大。这是 LWG 问题 2524......”来源(有问题的链接):https ://en.cppreference.com/w/cpp/numeric/随机/指数分布
切换到double
并不能解决这个问题,相反,它只会减少看到它的机会(或至少使它可以忽略不计)。正如 LWG 问题所指出的,根本问题是generate_canonical
(某些实现可以利用)在极少数情况下可能会返回 1.0,因此-log(1-generate_canonical())
可能会输出无穷大。在实践中,这float
比 with更有可能,因为与 with 相比,可以产生double
的数字要少得多(实际上是 2^24 而不是 2^53)。(无论如何,右尾分布的幼稚实现还有其他问题,例如指数分布;请参阅“重新调节分位数函数”。)generate_canonical
float
double
推荐阅读
- asp.net - JSON.parse 错误:项目发布后出现意外字符
- python-3.x - 使用 Python 请求对 DockerHub 进行 JWT 令牌身份验证
- jquery - jQuery 显示和淡入
- regex - 检查位数的正则表达式
- python - 子图中的自定义 xtick 标签
- spring-boot - Spring Boot 在服务中运行相同配置文件的多个实例
- python - Python - 记录字符串以前的内容
- php - 用于 php 文件的 Nginx try_files
- java - 是否可以在 Spring 中使用枚举实现策略模式
- python - 如何将 Pandas 数据拆分为对象中的 2 位小数