尝试使用std::generate_canonical
时遇到问题。根据我在cpp-reference.com的阅读,我希望std::generate_canonical
能够生成[0,1]范围内的数字。
但是,在最新的MSVC 2012(未安装CTP)上,std::generate_canonical
生成的数字全部为10 ^ 28(见下文)。实际上,Microsoft's documentation未提及std::generate_canonical
生成数字的范围。
Microsoft是否不符合此处的标准?或者是标准缺陷,因为它对std::generate_canonical
的行为含糊不清?在第二种情况下,如何编写代码以生成[0,1)范围内的随机浮点数?
请考虑以下示例代码,以便我尝试使用std::generate_canonical
。
#include <random>
#include <limits>
#include <iostream>
int main(int argc, char* argv[])
{
std::random_device rd;
// seed with true source of randomness
std::mt19937 _rng_generator(rd());
for(int n=0; n<10; ++n)
std::cout << std::generate_canonical<double,std::numeric_limits<double>::digits>(_rng_generator) << ' ';
return EXIT_SUCCESS;
}
我得到的输出示例:
4.85267e+028 2.76741e+028 3.17392e+028 5.84136e+028 1.0037e+028 4.87202e+028 2.53834e+028 4.233e+028 6.43922e+028 2.30694e+028
更新 我之前向Microsoft Connect报告了这个错误。该错误现已修复,修复程序将包含在MSVC 2014 RTM中。
答案 0 :(得分:6)
26.5.7.2函数模板generate_canonical [rand.util.canonical]
每个函数都是从本节中描述的模板中实例化的 26.5.7.2将提供的统一随机数生成器
g
的一个或多个调用的结果映射到指定的一个成员RealType
,如果g
生成的值g
i 是统一的 分布式,实例化的结果tj
,0≤tj
&lt; 1,是 按照以下规定尽可能均匀地分发。template<class RealType, size_t bits, class URNG> RealType generate_canonical(URNG& g);
此外,标准描述,此函数返回,其中
因此,此函数应返回从0到1的值。我认为,微软的实施在这里是错误的。
答案 1 :(得分:0)
您当前所指的cpp reference说:
“某些现有实现存在一个错误,如果RealType为float GCC,则偶尔会返回1.0 GCC#63176 LLVM#18767。这是LWG问题2524”
根据issue,“问题在于该标准指定了实现,而该实现不起作用。”
此问题于您发布此问题几年后的2015年8月20日开放。
答案 2 :(得分:-4)
以下是MSDN文档:
http://msdn.microsoft.com/en-us/library/ee462289.aspx
这是相应的原型:
template<class RealType,
size_t bits,
class Engine>
RealType generate_canonical(Engine& gen);
这是一个完整的例子:
http://msdn.microsoft.com/en-us/library/bb982398.aspx
// cl.exe /EHsc /nologo /W4 /MTd
#include <algorithm>
#include <array>
#include <iostream>
#include <ostream>
#include <random>
#include <string>
#include <vector>
using namespace std;
template <typename C> void print(const C& c) {
for (const auto& e : c) {
cout << e << " ";
}
cout << endl;
}
void test(unsigned int seed) {
cout << "Seed: " << seed << endl;
mt19937 engine(seed);
uniform_int_distribution<int> dist(-3, 5);
vector<int> v;
for (int i = 0; i < 30; ++i) {
v.push_back(dist(engine));
}
cout << "Randomized vector: ";
print(v);
array<string, 26> arr = { { "H", "He", "Li", "Be", "B", "C", "N", "O", "F",
"Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl", "Ar", "K", "Ca", "Sc",
"Ti", "V", "Cr", "Mn", "Fe" } };
shuffle(arr.begin(), arr.end(), engine);
cout << "Randomized array: ";
print(arr);
}
int main() {
cout << "--" << endl;
test(12345);
cout << "--" << endl;
random_device rd;
test(rd());
}