C++ 11 std :: uniform_real_distribution(-1,1)給出範圍[-1,1)中的數字。std :: uniform_real_distribution包含範圍
如何在範圍[-1,1]中得到均勻的實分佈?
實際上它可能並不重要,但邏輯上我試圖選擇一個在包容性範圍內的值。
C++ 11 std :: uniform_real_distribution(-1,1)給出範圍[-1,1)中的數字。std :: uniform_real_distribution包含範圍
如何在範圍[-1,1]中得到均勻的實分佈?
實際上它可能並不重要,但邏輯上我試圖選擇一個在包容性範圍內的值。
如果您以整數開始,這很容易考慮。如果你通過[-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)
也就是說,尋找下一個最大的雙值之後的值,並將其作爲最終值傳遞。
不幸的是,浮點分佈的實際實現不允許你如此精確。例如,uniform_real_distribution<float>
應該在給定的半範圍內產生值,但由於舍入問題,它實際上可能會在包含範圍內產生值。
Here'sgenerate_cannonical
問題的一個例子,其他real_distributions也會出現類似的問題。
很好,謝謝。 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
標準的浮點分佈不能提供精確度的最後一位精度,但相反會遇到舍入問題,這意味着以這種方式嘗試使用它們是不合適的。 – bames53 2015-12-08 21:57:44