Tre*_*key 6 c++ random floating-point nan uniform-distribution
如果我以下列方式生成浮点值:
template <typename T>
T RandomFromRange(T low, T high){
std::random_device random_device;
std::mt19937 engine{random_device()};
std::uniform_real_distribution<T> dist(low, high);
return dist(engine);
}
template <typename T>
T GetRandom(){
return RandomFromRange
(std::numeric_limits<T>::min(),std::numeric_limits<T>::max());
}
//produce floating point values:
auto num1 = GetRandom<float>();
auto num2 = GetRandom<float>();
auto num3 = GetRandom<float>();
//...
Run Code Online (Sandbox Code Playgroud)
是否有可能,我将永远得到一个NaN
,Inf
或-Inf
?
让我们考虑一下std::uniform_real_distribution
产生什么.
生成随机浮点值i,均匀分布在区间[a,b)
所以,这是在std::numeric_limits<foat>::min()
和之间std::numeric_limits<float>::max()
,包括前者,但不包括后者.这些限制会带来什么价值?他们返回FLT_MIN
和FLT_MAX
分别.那些是什么?
最小归一化正浮点数
最大可表示的有限浮点数
由于{正,负}无穷大,NaN都不在有限数范围内,因此不会生成它们.
正如克里斯托弗·奥雷斯(Christopher Oicles)所指出的那样,注意FLT_MIN
并且通过扩展,std::numeric_limits<foat>::min()
它是最小的正可表示值.
正如克里斯·多德所指出的那样,如果范围[min, max)
超出std::numeric_limits<float>::max()
,则会得到未定义的行为,在这种情况下,任何输出,包括生成无穷大都是可能的.
实际上,这会导致未定义的行为,因为std::uniform_real_distribution
(我的规范草案的第26.5.8.2.2节)要求:
explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0);
Requires: a ? b and b ? a ? numeric_limits<RealType>::max().
Effects: Constructs a uniform_real_distribution object; a and b correspond to
the respective parameters of the distribution.
Run Code Online (Sandbox Code Playgroud)
您的具体示例将溢出该numeric_limits
要求.
现在你可以构建一个std::uniform_real_distribution<double>
带std::numeric_limits<float>::min
/ max
作为边界,这应该是明确定义的.它也可能是你的例子适用于大多数实现(因为它们通常会促进浮点数在内部计算中加倍),但它仍然会遇到未定义的行为.
在它不起作用的实现上,我猜想最有可能生成失败模式Inf
,因为这b-a
将是生成的.
归档时间: |
|
查看次数: |
503 次 |
最近记录: |