"min to max" 均匀实数分布会产生 Inf、-Inf 还是 NaN?
Will "min to max" uniform real distribution produce Inf,-Inf, or NaN?
如果我按以下方式生成浮点值:
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>();
//...
我有可能找回 NaN
、Inf
或 -Inf
吗?
让我们考虑一下 std::uniform_real_distribution
生成的内容。
Produces random floating-point values i, uniformly distributed on the interval [a, b)
因此,介于std::numeric_limits<foat>::min()
和std::numeric_limits<float>::max()
之间,包括前者,但不包括后者。这些限制 return 的值是多少?他们分别 return FLT_MIN
和 FLT_MAX
。那么,那些是什么?
minimum normalized positive floating-point number
maximum representable finite floating-point number
因为 {positive,negative} 无穷大和 NaN 都不在有限数的范围内,所以不会生成它们。
正如 Christopher Oicles 所指出的,请注意 FLT_MIN
并且推而广之,std::numeric_limits<foat>::min()
是最小的 正 可表示值。
正如 Chris Dodd 所指出的, 如果 [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.
您的具体示例将超出 numeric_limits
要求。
现在您可以 构建一个 std::uniform_real_distribution<double>
以 std::numeric_limits<float>::min
/max
作为边界,并且应该明确定义。您的示例也可能适用于大多数实现(因为它们通常会在内部计算中将浮点数提升为双精度),但它仍然会遇到未定义的行为。
在它不起作用的实现中,我猜想最有可能的失败模式是生成 Inf
,因为那是 b-a
会生成的。
如果我按以下方式生成浮点值:
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>();
//...
我有可能找回 NaN
、Inf
或 -Inf
吗?
让我们考虑一下 std::uniform_real_distribution
生成的内容。
Produces random floating-point values i, uniformly distributed on the interval [a, b)
因此,介于std::numeric_limits<foat>::min()
和std::numeric_limits<float>::max()
之间,包括前者,但不包括后者。这些限制 return 的值是多少?他们分别 return FLT_MIN
和 FLT_MAX
。那么,那些是什么?
minimum normalized positive floating-point number
maximum representable finite floating-point number
因为 {positive,negative} 无穷大和 NaN 都不在有限数的范围内,所以不会生成它们。
正如 Christopher Oicles 所指出的,请注意 FLT_MIN
并且推而广之,std::numeric_limits<foat>::min()
是最小的 正 可表示值。
正如 Chris Dodd 所指出的, 如果 [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.
您的具体示例将超出 numeric_limits
要求。
现在您可以 构建一个 std::uniform_real_distribution<double>
以 std::numeric_limits<float>::min
/max
作为边界,并且应该明确定义。您的示例也可能适用于大多数实现(因为它们通常会在内部计算中将浮点数提升为双精度),但它仍然会遇到未定义的行为。
在它不起作用的实现中,我猜想最有可能的失败模式是生成 Inf
,因为那是 b-a
会生成的。