C++ 如何为自定义类型生成均匀分布的随机实数,而无需重新设计轮子?

C++ 如何为自定义类型生成均匀分布的随机实数,而无需重新设计轮子?,c++,random,floating-point,C++,Random,Floating Point,我打算将std::uniform\u real\u distribution与一些非内置的类似浮点的类型一起使用,例如or。但我得到的是 /opt/gcc-5.2/include/c++/5.2.0/bits/random.h:1868:7:错误:静态断言失败:模板参数不是浮点类型 来自g++5.2。下面是示例程序(使用g++-std=c++11-fext numeric literals test.cpp-o test编译): #包括 #包括 #包括 模板 无效测试() { std::随机_装

我打算将
std::uniform\u real\u distribution
与一些非内置的类似浮点的类型一起使用,例如or。但我得到的是

/opt/gcc-5.2/include/c++/5.2.0/bits/random.h:1868:7:错误:静态断言失败:模板参数不是浮点类型

来自g++5.2。下面是示例程序(使用
g++-std=c++11-fext numeric literals test.cpp-o test编译)

#包括
#包括
#包括
模板
无效测试()
{
std::随机_装置rd;
标准:mt19937 mt(rd());
标准:均匀实分布rnd(浮点(1),浮点(10));
}
int main()
{
test();
test();
test();
test();//不编译
test();//不编译
}
那么,如何为这些自定义类型生成均匀分布的随机实呢?有没有办法不重新发明轮子?

正如您从中看到的,
统一的真实分布定义为:

template< class RealType = double >
class uniform_real_distribution;
模板
类均匀实分布;
其中,
RealType
是:

生成器生成的结果类型。如果不是float、double或long double中的一个,则效果未定义


您的编译器似乎明确禁止使用自定义类型作为处理(比方说)不可接受类型的解决方案。因此,我认为您没有机会让它工作。

标准中定义的与
RealType
类型一起工作的标准随机数工具必须具有
float
double
long double
作为类型模板参数,如26.5.1.1.d所示:

在本第26.5款中,实例化模板的效果:

d) 具有名为
RealType
的模板类型参数的未定义,除非相应的模板参数是cv非限定参数,并且是
float
double
long double
中的一个

一种解决方案是用
boost::random::uniform\u real\u distribution
替换
std::uniform\u real\u distribution
。后者不接受非内置浮点类型。下面是一个合理类型的示例*:

#包括
#包括
#包括
模板
无效测试()
{
std::随机_装置rd;
标准:mt19937 mt(rd());
boost::random::均匀实分布rnd(浮点(1),浮点(10));
}
int main()
{
test();
test();
test();
test();
}

*
half\u float::half
不起作用,因为它与一个常量相乘会产生一个
float
,而
half\u float::half(float)
构造函数是显式的,Boost的实现没有显式地调用它,但实际的问题是,如果有的话,有什么好的替代方案,也就是说,我可以用它来代替我自己的统一分配的实现。@Ruslan你可以用
float
double
long double
作为一种类型。这就是全部。或者您正在寻找一种替代
统一实分布的方法吗?
?是的,我正在寻找一种适用于其他浮点类型的替代机制。@Ruslan它们与内置类型不同。使用标准模板库所能做的最好的事情就是编写一个生成器,它在内部使用
统一实分布
浮点分布
并返回所需的类型。无论如何,转换可能会削弱使用
统一实分布的好处。定义一个接受1到n个浮点并返回您最喜欢的浮点类型的函数怎么样?然后将随机浮点作为输入,可能作为默认参数。@lorro您的意思是仅仅是将浮点类型从内置类型转换为我需要的类型的函数吗?但这并不会使分布保持一致。我指的是数学意义上的“函数”:自定义浮点和N个标准浮点元素之间的1:1映射(如果浮点小于标准浮点,则反之亦然)。用ints:pseudocode:
int64_t getint64(int32_t a,int32_t b){return int64_t(a)@lorro更容易解释。为float定义这样一个函数的棘手部分是确保在
[a,b)与输入类型的值集相交
,它将给出与输出类型的值集相交的[a,b]上均匀分布的结果。
template< class RealType = double >
class uniform_real_distribution;
#include <random>
#include <boost/random/uniform_real_distribution.hpp>
#include <boost/multiprecision/float128.hpp>

template<typename Float>
void test()
{
    std::random_device rd;
    std::mt19937 mt(rd());
    boost::random::uniform_real_distribution<Float> rnd(Float(1),Float(10));
}

int main()
{
    test<float>();
    test<double>();
    test<long double>();
    test<boost::multiprecision::float128>();
}