boost I 数学领域常用的六个库

目录

一、math.constants 数学常量

二、integer 编译期整数相关计算

(一)integer_traits

(二)整数类型定义

1.cstdint.hpp 使用typedef提供一系列整数类型定义

2.integer.hpp 使用模板类提供一系列整数类型定义

三、rational 分数

(一)创建与赋值

(二)访问分子分母

(三)类型转换

1.转bool

2.转整数/浮点数

(四) 其他运算

1.取绝对值

2.最大公约数、最小公倍数

四、ratio 编译期分数

五、CRC 循环冗余码

(一)crc_32_type

六、random 随机数

(一)随机数发生器

1.随机数发生器基本接口

(二)随机数分布器

1.boost::uniform_smallint 在小整数区间内的均匀分布

2.boost::random::uniform_int_distribution 在任意整数域内的均匀分布

3.boost::uniform_01 在区间[0,1]上的实数连续均匀分布

4.boost::uniform_real 在区间[a,b)上的实数连续均匀分布

5.boost::normal_distribution 正态分布

(三)变量发生器


一、math.constants 数学常量

        math.constants 库提供了π、e、根号2、根号3、ln2等常用的数学常数,这些值都是编译期的常数,运行时没有开销,所以其运行效率很高。

        这些数学常数,支持 float、double、long double 精度,而且还支持自定义类型以获得更高的精度。为了方便使用,math.constants 库在名字空间boost::math 里又定义了 3 个子名字空间,分别是 float_constants、 double_constants 和long_double_constants,我们可以直接使用这些名字空间里对应精度的常数。

#include <boost/math/constants/constants.hpp>
void TestMathConstants()
{
    //std::cout << "设置显示精度为10位" << std::setprecision(10)<<std::endl;
    std::cout << "半径为2的圆的面积:" << boost::math::float_constants::pi * 2 * 2 << std::endl;
    std::cout << "(根号2)/2:" << boost::math::double_constants::root_two / 2 << std::endl;
    std::cout << "(根号Π):" << boost::math::float_constants::root_pi << std::endl;
    //半径为2的圆的面积:12.5664
    //(根号2)/2:0.707107
    //(根号Π):1.77245

    //设置显示精度为10位
    //半径为2的圆的面积:12.56637096
    //(根号2) / 2:0.7071067812
    //(根号Π):1.772453904
}

二、integer编译期整数相关计算

        C++98 标准在头文件 < limits > 里定义了模板类std::numeric_limits,它使用模板特化技术给出了 int、double 等数据类型的相关特性,如最大值和最小值、是否有符号等。这些特性大部分是编译期的常量,但最大值和最小值函数却不是常量,只能在运行时使用,这在进行泛型编程时会带来一些不便。

        C++11 标准修复了这个缺点,使用新的关键字constexpr令这两个函数成为编译期常量。而Boost库的 integer_traits 组件派生自 std::numeric_limits , 使用另一种方式达到了同样的目的。它已被收入 C ++ 标准。

C++ const 和 constexpr 的区别?

对于修饰Object来说,const并未区分出编译期常量和运行期常量,constexpr限定在了编译期常量。

对于修饰函数来说,constexpr修饰的函数,返回值不一定是编译期常量。

(一)integer_traits

        integer_traits类使用了多继承,继承自std::numeric_limits及detail::integer_traits_base类,integer_traits_base类使用BOOST_STATIC_CONSTANT实现了const_min和const_max两个静态成员变量(可用于编译期的泛型编程)。

#include <boost/integer_traits.hpp>
void TestInteger()
{
    std::cout << boost::integer_traits<int>::const_max << std::endl; //2147483647
    std::cout << boost::integer_traits<bool>::const_min << std::endl;//0
    std::cout << boost::integer_traits<long>::is_signed << std::endl;//1
    std::cout << boost::integer_traits<int>::min() << std::endl;
    int a[boost::integer_traits<bool>::const_max];//int a[1]
    int b[boost::integer_traits<bool>::max()];//int b[1]
}

(二)整数类型定义

1.cstdint.hpp 使用typedef提供一系列整数类型定义

        cstdint.hpp 使用typedef提供一系列整数类型定义。<boost/cstdint.hpp>基于 1999 年 C 标准中规定的 < stdint.h >,为标准的整型数提供了精确的定义,而且如果编译器提供了 < stdint.h >,那么就会自动包含它以保证兼容性。

        <boost/cstdint.hpp>以形如 " xxx_yyy#_t " 的typedef提供了各种宽度 ( 二进制位 ) 的整数的精确定义(如int_fast16_t)

typedef signed char        int_fast8_t;
typedef int                int_fast16_t;
typedef int                int_fast32_t;
typedef long long          int_fast64_t;
typedef unsigned char      uint_fast8_t;
typedef unsigned int       uint_fast16_t;
typedef unsigned int       uint_fast32_t;
typedef unsigned long long uint_fast64_t;
  • xxx:表明该类型是否有正负符号。有符号数为 int ,无符号数是 uint 。
  • yyy:表明该类型的特性。 least 表示该类型至少具有 # 位的宽度(可能会比 # 宽); fast 表示该类型不仅具有 least 的特性,而且是 CPU 处理速度最快的类型;如果没有 yyy 标识,则该类型是一个精确宽度的类型,其宽度恰好是 # 位。
  • #:表明该类型的宽度,可以是 8 、 16 、 32 、 64 ,以位为单位。
  • t:t是type的缩写,遵循C++标准对类型的定义,如size_t、wchar_t等。

        <boost/cstdint.hpp>里还有两个最大宽度的整数类型: intmax_t 和 uintmax_t ,用来表示编译器支持的最大整数,可以兼容任意其他整数类型。

        在流输出 int8_t 类型时需将其转换为 short型,否则流输出会认为是一个字符类型,输出其ASClI码,而不输出数字。

    #include <boost/cstdint.hpp>

    boost::int_fast16_t i16t = 100;//最快的有符号16位整数
    boost::intmax_t imt = 101;//编译器支持的最大有符号整数类型
    boost::uintmax_t uimt = 102;//编译器支持的最大无符号整数类型
    boost::int8_t i8t = 97;//一个简单的8位有符号整数:signed char
    std::cout << "i8t:" << i8t << "," << (short)i8t << std::endl;//i8t:a,97

2.integer.hpp 使用模板类提供一系列整数类型定义

        <boost/integer.hpp>与<boost/cstdint.hpp>的功能类似,但它是使用模板类来提供一系列整数类型定义。<boost/integer.hpp>内置两组模板类:模板参数为类型的boost::int_fast_t及模板参数为整数位数或数值的int_t、uint_t、int_max_value_t、int_min_value_t、uint_value_t。

        整数类型模板类内仅有 typedef ,没有其他数据成员或成员函数,所以这些类运行时不会产
生任何开销(元计算发生在编译期 ) ,与使用内置整数类型或 Boost 整数类型同样高效。

模板参数为类型的boost::int_fast_t:

  template< typename LeastInt >
  struct int_fast_t
  {
     typedef LeastInt fast;
     typedef fast     type;
  }; // imps may specialize

        int_fast_t 的内置类型 fast 可以自动给出模板参数类型 Leastnt 相应的处理速度最快的整数类型。如果 Leastint 已经是处理速度最快的整数,则返回 Leastint 。

模板参数为整数位数或数值的模板类:

        内置类型 least 返回支持的最小整数类型, fast 返回最快的整数类型。

        int_t 和 uint_t 的模板参数指明需要的整数宽度(以 bit 为单位 ) , 不一定是 8 的整数倍 , 但必须是正整数 , 内部类型 least 和 fast 分别返回能容纳Bits位的最小和最快的整数类型。

        int_max_value_t/int_min_value_t的模板参数表明要容纳的最大/最小整数数值,该参数必须是一个正/负整数,内部类型least和 fast 分别返回能容纳 MaxValue/MinValue 的最小和最快的有符号整数类型。

        uint_value_t 与 int_max_value_t 类似,它的模板参数表明要容纳的最大整数数值,参数必须是一个正整数,内部类型 least 和 fast 分别返回能容纳Value的最小和最快的无符号整数类型。

    #include <boost/integer.hpp>
    #include <boost/type_index.hpp>

    //int_fast_t模板类
    typedef  boost::int_fast_t<int>::fast intfast;//int类型的最快类型
    std::cout << "类型名称:" << boost::typeindex::type_id<intfast>().pretty_name() << ",size=" << sizeof(intfast) << "字节" << std::endl;//类型名称:int,size=4字节

    //int_t模板类
    typedef boost::int_t<8>::fast i8;//可容纳8位的最快整数
    std::cout << "类型名称:" << boost::typeindex::type_id<i8>().pretty_name() << ",size=" << sizeof(i8) << "字节" << std::endl;//类型名称:signed char,size=1字节
    //int_max_value_t模板类
    typedef  boost::int_max_value_t<100>::fast im100;//可处理100的最快整数
    std::cout << "类型名称:" << boost::typeindex::type_id<im100>().pretty_name() << ",size=" << sizeof(im100) << "字节" << std::endl;//类型名称:signed char,size=1字节
    //uint_value_t模板类
    typedef  boost::uint_value_t<100>::fast ui100;//可处理100的最快无符号整数
    std::cout << "类型名称:" << boost::typeindex::type_id<ui100>().pretty_name() << ",size=" << sizeof(ui100) << "字节" << std::endl;//类型名称:unsigned char,size=1字节

三、rational 分数

        boost.rational支持分数的概念,它基于 C ++ 的内建整数类型,数字运算时没有精度损失,它可以应用于金融财务等需要准确值的领域注。

        rational类内部把有理数用“分子 / 分母”的形式保存,运算时使用最大公约数、最小公倍数等操作使其规范化。

(一)创建与赋值

        rational有三种形式的构造函数,默认构造函数(无参 ) 创建一个值为零的有理数,单参数的构造函数创建一个整数 ( 分母为 1 ),双参数的构造函数创建一个规范化的分数。

        rational重载了 operator = ,可以直接从另一个整数赋值,或者使用成员函数 assign( )接收“分子 / 分母”形式的两个整数参数赋值。

#include <boost/rational.hpp>

void StudyMathClass::TestRational()
{
    //创建与赋值
    boost::rational<int> zero;          //     0/1
    boost::rational<int> rational1(2);  //     2/1
    boost::rational<int> pi(22, 7);     //     22/7

    boost::rational<int> rational2;     //     0
    rational2.assign(5, 6);             //     5/6
    std::cout << rational2 << std::endl;
    rational2 = 10;                     //     10/1
    std::cout << rational2 << std::endl;
    rational2 += pi;
    std::cout << rational2 << std::endl;//     92/7
}

(二)访问分子分母

        成员函数 numerator( )和 denominator( )可以直接访问 rational 对象的分子和分母,但返回的是个右值,只能读而不能写。

//访问分子分母
std::cout << "分母:" << pi.denominator() << ",分子:" << pi.numerator() << std::endl;  //分母:7,分子:22

(三)类型转换

1.转bool

        与整数的 bool 含义一样,rational 也可以在 bool语境里直接隐式转换为 bool 类型,当它的值是 0时为 false,否则为 true。

        rational也重载了逻辑 " 非 " 操作符 operator !,它以相反的规则转换为 bool 类型。

    if (rational2)                          //rational2不为0
    {
        rational2 /= rational1;
        std::cout << rational2 << std::endl;//  46/7
    }

2.转整数/浮点数

        除 bool 以外,rational 不能隐式转换成任何其他类型 ( 即使是从分母为 1 的有理数转换成整数 ) , 而必须使用 rational_cast 函数。这个函数模仿了标准库的转型操作符 , 可以显式地转换成其他数字类型。

std::cout << "2/1转换成整数:" << boost::rational_cast<int>(rational1) << std::endl;    //2/1转换成整数:2
std::cout << "46/7转换成小数:" << boost::rational_cast<double>(rational2) << std::endl;//46/7转换成小数:6.57143

(四) 其他运算

1.取绝对值

        rational没有实现到 float / double 的隐式转换,故不能直接使用 sqrt( )、pow( )等标准 C 函数(它们要求参数是 int、double 等类型)。但取绝对值的 abs( )函数是一个例外,因为 rational 实现了对它的重载。

boost::rational<int> rational3(-10, 12);
std::cout << "-10/12取绝对值:" << boost::abs(rational3) << std::endl;    //-10/12取绝对值:5/6

2.最大公约数、最小公倍数

        rational库还提供了两个工具函数:最大公约数gcd( )和最小公倍数 Icm( )。

//求最大公约数
std::cout << "10和5的最大公约数:" << boost::gcd(10, 5) << std::endl;//10和5的最大公约数:5
std::cout << "10和5的最小公倍数:" << boost::lcm(10, 5) << std::endl;//10和5的最小公倍数:10

四、ratio 编译期分数

        ratio完全实现了 C ++ 标准里的内容,它专门用于表示数字的单位,是编译期的分数,其作用类似于 math.constants 里的数学常量。它已被收入 C ++ 标准。虽然它与rational一样,它们的处理对象都是有理数,但它们是两个完全不同的领域。

        ratio有两个模板参数,都是整数类型,它们一起定义了编译期的分数 N / D。如果分母是 1,那么第二个模板参数可以省略不必写出 。ratio主要的成员是 num 和 den , 它们和 rational —样分别表示分子和分母 , 但不同的是它们都是静态成员,所以能够在编译期进行各种运算。

        ratio实现了 C ++ 标准里定义的全部的数字单位 ,包括常见的 nano 和 giga , 还有比它们更小和更大的单位 ( 当然 , " 1 " 和 " 0 " 这两个单位是无须定义的 )。

        模板类 ratio_string 可以获得 ratio 的字符串描述信息。

        ratio_string 在模板参数里接收 ratio 和 char 类型,然后用静态成员函数 symbol ( ) 和prefix ( ) 输出对应的字符串形式,通常是" [ N / D ] " 的形式,但对 kilo、mega 等预定义的ratio单位则有特化的版本。

#include <boost/ratio.hpp>
void TestRatio()
{
    std::cout << "分母:" << boost::ratio<5, 8>::den << std::endl;
    std::cout << "分子:" << boost::ratio<5, 8>::num << std::endl;
    std::cout << "giga is " << boost::ratio_string<boost::giga, char>::symbol() << std::endl;//giga is G
    std::cout << "nano is " << boost::ratio_string<boost::nano, char>::symbol() << std::endl;//nano is n
    std::cout << "自定义ratio字符串:" << boost::ratio_string< boost::ratio<5, 8>, char>::symbol() << std::endl; //自定义ratio字符串:[5/8]
}

五、CRC循环冗余码

        CRC(循环冗余校验码)是一种被广泛应用的错误验证机制,它使用特定的规则处理数据,计算出一个校验和,并与数据一起发送给接收方。接收方使用同样的规则计算 CRC ,如果两个计算结果一致则说明传输正确,否则表明传输过程发生错误。

        crc库提供了两个类用于计算循环冗余校验码:一个是 crc_basic ,它以 bit 为单位进行计算,速度慢,仅供理论研究;另一个是 crc_optimal ,它是优化过的处理机,以 byte 为单位进行计算,速度很快,适合实际应用。 crc 库的所有实现均基于 crc_optimal。

template < std::size_t Bits, BOOST_CRC_PARM_TYPE TruncPoly = 0u,
           BOOST_CRC_PARM_TYPE InitRem = 0u, BOOST_CRC_PARM_TYPE FinalXor = 0u,
           bool ReflectIn = false, bool ReflectRem = false >
class crc_optimal;

        crc_optimal 有 6 个模板参数 , 但我们通常无须关心这些细节 , 因为这涉及 CRC 计算的许多数学理论知识。只有第一个模板参数 Bits 是比较重要的 , 它定义了 CRC 模板类的位数 , 一般取值为16或 32。

        crc_optimal 类的模板参数过多,实际使用时很不方便,所以 crc 库基于 crc _ optimal 预定义了 4个实现类:crc_16_type 、 crc_ccitt_type 、crc_xmodem_type 和 crc_32_type。这 4 个类实现了历史上已经被广泛使用的 CRC 计算方法,前3个是 16 位的 CRC ( 2 字节 ) ,第 4 个是 32 位的CRC ( 4 字节 )。

(一)crc_32_type

typedef crc_optimal<32, 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc_32_type;

        成员函数 process_byte ( ) 一次只能处理 1 个字节。

        process_bytes ( ) 和 process_block ( ) 函数则可以处理任意长度的数据块 , 两者的区别在于输入参数:process_bytes ( ) 用 " 数据块 + 数据块长度 " 的形式 , 而 process_block ( ) 接收数据块的开始指针和结束指针。

        在任何时候, crc_optimal 都可以调用checksum( )函数获得当前已计算出的 CRC ,或者调用 reset( )重置计算结果。

        crc_optimal 还重载了括 , 号操作符operator ( ) , 它有两种用法 :

  • 不带参数的形式直接返回 CRC , 相当于调用 checksum ( ) , 可以很方便地获取返回值 ;
  • 带参数的形式接收 1 个字节 , 相当于调用 process_byte ( ) , 因此可以把 crc_optimal 对象当作函数对象传递给标准算法。
#include <boost/crc.hpp>
void TestCRC()
{
    boost::crc_32_type crc;
    std::cout << crc.checksum() << std::endl;//0
    //process_byte
    crc.process_byte('a');
    std::cout << crc.checksum() << std::endl;//3904355907
    //process_bytes
    crc.reset();
    crc.process_bytes("123456", 6);
    std::cout << crc.checksum() << std::endl;//158520161
    //process_block
    crc.reset();
    const char* ch = "123456";
    crc.process_block(ch, ch + 6);
    std::cout << crc.checksum() << std::endl;//158520161
    //重载operator()操作符
    std::cout << crc() << std::endl;//158520161

    crc.reset();
    crc('a');
    std::cout << crc() << std::endl;//3904355907

    //std::for_each 算法接收一个单参的函数对象 , 把它拷贝一个副本在算法内部使用 , 不会影响原
    //函数对象 ( crc32 ) . 算法在数据块区间内逐个元素调用函数对象的 operator ( ) , 即process_byte 
    //( ) , 以计算 CRC , 循环完成后返回存储的函数对象副本——另一个 crc_32_type对象 , 因此可以再调用
    //无参版的 operator ( ) 来获取 CRC。

    crc.reset();
    std::cout << std::for_each(ch, ch + 6, crc)() << std::endl;//158520161
}

六、random随机数

        random 库专注于伪随机数的实现,有多种算法可以产生高质量的伪随机数,并提供随机数发生器、分布等很多有用的数学、统计学相关概念。它已被收入 C ++ 标准。

        random 库也支持真随机数发生器,具体可参考《罗剑峰·Boost程序库完全开发指南:深入C++“准”标准库 第5版》

(一)随机数发生器

       random库提供了30多个随机数发生器,常用的有rand48、mt19937和lagged_fibonacci19937,它们产生随机数的速度由高到低,产生的随机数质量和内存需求则由低到高。虽然这些随机数发生器使用的算法不同,实现也有差异,但它们的基本接口是类似的。(以下代码以rand48为例)

1.随机数发生器基本接口

构造函数和成员函数 seed ( )为发生器赋一个种子值。

可以用静态成员函数 min( )和 max( )获得随机数的最大值和最小值。

operator( )产生一个随机数,也可以用 generate( )填充一个迭代器区间。

因为伪随机数序列是固定的,我们也可以使用 discard( )函数从序列中丢弃(忽略)一些。

        伪随机数发生器在程序中应尽量少调用构造操作。原因有两个:一是伪随机数发生器的构造成本相当昂贵,越是高质量的伪随机数发生器越需要初始化大量的内部状态,需要大量的时间和空间开销;二是由于构造发生器提供的种子一般使用系统时间,如果两个发生器构造的时间间隔很短,那它们的种子值很可能是相同的,从而得到两个行为相同的伪随机数发生器,令随机数失去意义。

        随机数发生器都允许拷贝、赋值,在某些情况下这种能力是很有用的:拷贝后的副本完全复制了原随机数发生器的状态,可以产生相同的随机数序列,可用于再现测试。

#include <boost/random.hpp>
#include <boost/nondet_random.hpp>
void TestRandom()
{
    boost::rand48 random1(std::time(0));

    std::cout << "最大随机数:" << random1.max() << ",最小随机数:" << random1.min() << std::endl;//最大随机数:2147483647,最小随机数:0

    std::cout << "随机一个数:" << random1() << std::endl;//随机一个数:1313738086

    std::vector<int> _vector(10);
    random1.generate(_vector.begin(), _vector.end());
    for (auto i : _vector)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
}

(二)随机数分布器

        随机数发生器能够产生高质量的随机数,但它产生的随机数都是整数类型,这些整数类型均匀分布在整数域。而很多时候我们需要的是某些具有特定要求的随机数,如在指定区间内的任意整数、 [ 0 , 1 ) 内的实数、正态分布等,前面提到的随机数发生器显然无法满足要求。

        random库为此提出了随机数分布器的概念,把随机数发生器产生的整数域随机数映射到另一种分布,提高了代码的复用性。

        为了方便设置,有的随机数分布器类内部会定义专门的 param_type 类,它相当于一个 pair,表示分布使用的参数,通常可以用成员函数 a( )和b( )获得区间的端点。随机数分布器同样使用 operator( )产生随机数,但它需要传入一个随机数发生器( Engine )作为参数。

1.boost::uniform_smallint 在小整数区间内的均匀分布

        随机数分布器uniform_smallint 实现了在小整数区间内的均匀分布。它的模板参数是分布的整数类型,默认为 int ,构造函数指定分布区间的最大值和最小值。其他接口与伪随机数发生器类似,同样可以用 operator ()来获得随机数,同时它还提供 a( )/ b( )和 min( )/ max( )函数返回分布映射的区间范围。

    boost::rand48 random2(std::time(0));
    boost::uniform_smallint<int> _uniformsmallint(0,10);
    std::cout << "左区间:" << _uniformsmallint.a() << ",右区间:" << _uniformsmallint.b() << std::endl;//左区间:0,右区间:10
    for (size_t i = 0; i < 10; i++)
    {
        std::cout << _uniformsmallint(random2) << " ";//7 3 9 6 0 6 0 6 6 10
    }

2.boost::random::uniform_int_distribution 在任意整数域内的均匀分布

    boost::rand48 random2(std::time(0));
    boost::random::uniform_int_distribution<int> _uniform_int_distribution(0, 10);
    std::cout << "左区间:" << _uniform_int_distribution.a() << ",右区间:" << _uniform_int_distribution.b()<<std::endl;//左区间:0,右区间:10
    for (size_t i = 0; i < 10; i++)
    {
        std::cout << _uniform_int_distribution(random2) << " ";//5 9 3 0 10 10 7 3 6 10
    }

3.boost::uniform_01 在区间[0,1]上的实数连续均匀分布

        随机数分布器 uniform_01 实现了在 [ 0 , 1 ] 区间内的小数的均匀分布。它的模板参数是产生的浮点数类型,默认是 double ,它的其他接口与uniform_smallint 相同。

    boost::rand48 random2(std::time(0));
    boost::uniform_01<float> _uniform01;
    std::cout << "左区间:" << _uniform01.min() << ",右区间:" << _uniform01.max() << std::endl;//左区间:0,右区间:1
    for (size_t i = 0; i < 10; i++)
    {
        std::cout << _uniform01(random2) << " ";//0.892299 0.326378 0.929312 0.372843 0.622348 0.105996 0.965308 0.751108 0.0850656 0.716774
    }

4.boost::uniform_real 在区间[a,b)上的实数连续均匀分布

        随机数分布器 uniform_real/uniform_real_distribution 是uniform_01 在任意实数区间的扩展 , 它实现了在任意区间内的实数均匀分布。它的模板参数是产生的浮点数类型 , 默认是 double。其构造函数传入实数区间的两个端点 , 默认位于 [ 0 , 1 ) , 其他接口与 uniform_smallint 相同。

    boost::rand48 random2(std::time(0));
    boost::uniform_real<float> _uniform_real(0,100);
    std::cout << "左区间:" << _uniform_real.min() << ",右区间:" << _uniform_real.max() << std::endl;//左区间:0,右区间:1
    for (size_t i = 0; i < 10; i++)
    {
        std::cout << _uniform_real(random2) << " ";//57.2176 43.5958 27.9507 75.4686 17.3125 6.56545 83.5295 87.697 81.1198 57.4365
    }

5.boost::normal_distribution 正态分布

        随机数分布器 normal_distribution 实现了正态分布。它的模板参数是产生的浮点数类型,默认是double。构造函数传入均值和方差 ( 注意它的param_type 表示的不是分布的区间 ),默认是 0和 1。成员函数 mean ( ) 和 sigma ( ) 分别返回分布的均值和方差。

    boost::rand48 random2(std::time(0));
    boost::normal_distribution<> _normal_distribution(2, 2);//均值和方差
    std::cout << "均值:" << _normal_distribution.mean() << ",方差:" << _normal_distribution.sigma() << std::endl;//左区间:0,右区间:1
    for (size_t i = 0; i < 10; i++)
    {
        std::cout << _normal_distribution(random2) << " ";//0.694073 0.688351 5.09917 2.02174 3.61979 4.0144 5.01054 -0.172534 0.287698 -0.755944
    }

(三)变量发生器

        有了随机数发生器和随机数分布器,已经基本可以解决大部分与随机数相关的问题了。但为了方便使用, random 库还提供一个模板类variate_generator ( 变量发生器),它组合了随机数发生器和随机数分布器,使产生随机数更加容易、便捷。

        variate_generator 的模板参数是随机数发生器Engine和随机数分布器 Distribution:

  • Engine 的类型可以是 T (原始类型)、 T * (指针类型)或T & (引用类型)
  • Distribution 的类型则必须是T(原始类型),而不能是指针类型或引用类型。

        variate_generator 在构造函数中指定随机数发生器和随机数分布器的实例,可以用 engine( )、distribution( )获得随机数发生器和随机数分布器的引用, operator()产生随机数。

        variate_generator 也是可以拷贝和赋值的,这意味着它同伪随机数发生器一样可以保存状态以备后用,但如果模板参数的 Engine 是引用类型则无法拷贝、赋值。

    boost::rand48 _random3(std::time(0));
    boost::uniform_int<> _uniformInt(0, 100);
    boost::variate_generator<boost::rand48, boost::uniform_int<>> _gen(_random3, _uniformInt);
    for (size_t i = 0; i < 10; i++)
    {
        std::cout << _gen() << " ";//89 70 44 31 7 97 14 20 21 2
    }

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值