2016-04-24 69 views
6

如果我產生浮點值以下列方式:將「最小到最大」均勻實分佈產生Inf,-Inf還是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>(); 
//... 

是否有可能,我將永遠得到一個NaNInf-Inf

+1

鑑於沒有一個落入[min,max]範圍內,那麼大概不會。 –

回答

9

讓我們來考慮一下std::uniform_real_distribution生成的內容。

產生了隨機的浮點值I,在區間[a,b)中

所以,這是std::numeric_limits<foat>::min()std::numeric_limits<float>::max(),包括前者,但不包括後者之間均勻地分佈。這些限制返回什麼值?他們分別返回FLT_MINFLT_MAX。那麼,那些是什麼?

最小標準化浮點數

最大可表示的有限浮點數

由於既不{正,負}無窮大,也不NaN的是有限數的範圍內,不,他們沒有生成。

正如指出的克里斯托弗Oicles,要注意的是FLT_MIN推而廣之,std::numeric_limits<foat>::min()最小積極表示值。

正如指出的多德,如果[min, max)範圍超過std::numeric_limits<float>::max(),那麼你會得到不確定的行爲,並在這種情況下任何輸出,包括生成無窮將是可能的。

+1

對於浮點類型,'std :: numeric_limits :: min()'是一個正值(最小的非零正值)。和差異:'std :: numeric_limits :: max() - std :: numeric_limits :: min()'通常結束等於'std :: numeric_limits :: max()'(肯定不會更大,在任何情況)。所以我不確定Trevor是否知道這個問題,但是他的範圍選擇確實避免了分配中的不確定行爲。 –

+0

@ChristopherOicles好點,我沒有意識到這一點。我已經將其納入我的答案。 – user2079303

6

實際上,這會導致不確定的行爲,因爲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將生成的。