2013-04-25 222 views

回答

14

如果您以整數開始,這很容易考慮。如果你通過[-1,1),你會得到-1, 0。既然你想包含1,你可以通過[-1,(1 + 1))或[-1,2)。現在你得到-1, 0, 1

你想要做同樣的事情,但雙打:

借用this answer

#include <cfloat> // DBL_MAX 
#include <cmath> // std::nextafter 
#include <random> 
#include <iostream> 

int main() 
{ 
    const double start = -1.0; 
    const double stop = 1.0; 

    std::random_device rd; 
    std::mt19937 gen(rd()); 

    // Note: uniform_real_distribution does [start, stop), 
    // but we want to do [start, stop]. 
    // Pass the next largest value instead. 
    std::uniform_real_distribution<> dis(start, std::nextafter(stop, DBL_MAX)); 

    for (auto i = 0; i < 100; ++i) 
    { 
    std::cout << dis(gen) << "\n"; 
    } 
    std::cout << std::endl; 
} 

(見代碼運行here

也就是說,尋找下一個最大的雙值之後的值,並將其作爲最終值傳遞。

+1

很好,謝謝。 VS2012似乎沒有這個功能,但幸運的是它在[數學工具包]中有它(http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/utils/ next_float/nextafter.html) – 2013-04-25 23:06:07

+0

標準的浮點分佈不能提供精確度的最後一位精度,但相反會遇到舍入問題,這意味着以這種方式嘗試使用它們是不合適的。 – bames53 2015-12-08 21:57:44

1

不幸的是,浮點分佈的實際實現不允許你如此精確。例如,uniform_real_distribution<float>應該在給定的半範圍內產生值,但由於舍入問題,它實際上可能會在包含範圍內產生值。

Here'sgenerate_cannonical問題的一個例子,其他real_distributions也會出現類似的問題。