C++ c++;两个整数之间使用WELL512的随机数

C++ c++;两个整数之间使用WELL512的随机数,c++,random,generator,C++,Random,Generator,我看到这个问题可能已经在这里得到了回答: 然而,它并不十分友好,也没有提供如何在“真实世界”代码中使用它的示例 以下是我目前拥有的: #define m (unsigned long)2147483647 #define q (unsigned long)127773 #define a (unsigned int)16807 #define r (unsigned int)2836 static unsigned long seed; void x_srandom(u

我看到这个问题可能已经在这里得到了回答:

然而,它并不十分友好,也没有提供如何在“真实世界”代码中使用它的示例

以下是我目前拥有的:

#define m (unsigned long)2147483647
#define q (unsigned long)127773    
#define a (unsigned int)16807
#define r (unsigned int)2836    

static unsigned long seed;    
void x_srandom(unsigned long initial_seed);
unsigned long x_random(void);    

void x_srandom(unsigned long initial_seed)
{
    seed = initial_seed;
}    

unsigned long x_random(void)
{
    int lo, hi, test;

    hi = (seed / q);
    lo = (seed % q);

    test = (a * lo - r * hi);

    if (test > 0)
        seed = test;
    else
        seed = (test + m);

    return (seed);
}

int RANDOM(int from, int to)
{
    if (from > to)
    {
        int tmp = from;
        from = to;
        to = tmp;
    }
    return ((x_random() % (to - from + 1)) + from);
}

// Real world function using RANDOM()
void testFunction()
{
    printf("A random number between 1 and 1000 is %d \r\n", RANDOM(1, 1000));
    printf("A random number between 36 and 100 is %d \r\n", RANDOM(36, 100));
    printf("A random number between 1 and 2147483647 is %d \r\n", RANDOM(1, 2147483647));
    printf("A random number between 1 and 5 is %d \r\n", RANDOM(1, 5));
}
上面的例子展示了实现它所需要知道的一切


我想用WELL512来确定我的随机数,而不是像上面的例子那样确定我目前的随机数。

现在确实是时候不再使用%来生成分布了

对我来说,您应该使用WELL512作为统一的随机数生成器(就像标准库中的mt19937)。将其包装在一个类中,该类为result_type公开typedef(或使用)。在您的情况下,这可能是未签名的long。然后需要两个constexpr来表示min()和max()。这将是0和ULONG_MAX。最后,您需要公开返回单个无符号long的运算符()

然后将
中的功能与发动机一起使用

class well512 {
public:
    typedef unsigned long result_type;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return ULONG_MAX; }
    result_type operator()() { /* return some value from the underlying well512 implementation */ }
};

int main()
{
    well512 engine();
    std::uniform_int_distribution<> dist { 1, 5 };

    for (int i = 0; i != 10; ++i)
    {
        std::cout << dist(engine) << std::endl;
    }
    return 0;
}
class-well512{
公众:
typedef无符号长结果_type;
静态constexpr结果_type min(){return 0;}
静态constexpr result_type max(){return ULONG_max;}
result_type operator()(){/*从底层well512实现返回一些值*/}
};
int main()
{
well512引擎();
std::均匀分布区{1,5};
对于(int i=0;i!=10;++i)
{

std::cout现在确实是时候不再使用%来生成分布了

对我来说,您应该使用WELL512作为统一的随机数生成器(就像标准库中的mt19937)。您将其封装在一个类中,该类公开了结果类型的typedef(或using)。在您的情况下,它可能是无符号长的。然后,您需要两个constepr来表示min()和max()。这将是0和ULONG_MAX。最后,您需要公开返回单个无符号long的运算符()

然后将
中的功能与发动机一起使用

class well512 {
public:
    typedef unsigned long result_type;
    static constexpr result_type min() { return 0; }
    static constexpr result_type max() { return ULONG_MAX; }
    result_type operator()() { /* return some value from the underlying well512 implementation */ }
};

int main()
{
    well512 engine();
    std::uniform_int_distribution<> dist { 1, 5 };

    for (int i = 0; i != 10; ++i)
    {
        std::cout << dist(engine) << std::endl;
    }
    return 0;
}
class-well512{
公众:
typedef无符号长结果_type;
静态constexpr结果_type min(){return 0;}
静态constexpr result_type max(){return ULONG_max;}
result_type operator()(){/*从底层well512实现返回一些值*/}
};
int main()
{
well512引擎();
std::均匀分布区{1,5};
对于(int i=0;i!=10;++i)
{
std::能像这个用户515430吗

#define m  (unsigned long)2147483647

#define W 32
#define R 16
#define P 0
#define M1 13
#define M2 9
#define M3 5

#define MAT0POS(t,v) (v^(v>>t))
#define MAT0NEG(t,v) (v^(v<<(-(t))))
#define MAT3NEG(t,v) (v<<(-(t)))
#define MAT4NEG(t,b,v) (v ^ ((v<<(-(t))) & b))

#define V0            STATE[state_i                   ]
#define VM1           STATE[(state_i+M1) & 0x0000000fU]
#define VM2           STATE[(state_i+M2) & 0x0000000fU]
#define VM3           STATE[(state_i+M3) & 0x0000000fU]
#define VRm1          STATE[(state_i+15) & 0x0000000fU]
#define VRm2          STATE[(state_i+14) & 0x0000000fU]
#define newV0         STATE[(state_i+15) & 0x0000000fU]
#define newV1         STATE[state_i                 ]
#define newVRm1       STATE[(state_i+14) & 0x0000000fU]

#define FACT 2.32830643653869628906e-10

static unsigned int state_i = 0;
static unsigned int STATE[R];
static unsigned int z0, z1, z2;

void InitWELLRNG512a(unsigned int *init){
    int j;
    state_i = 0;
    for (j = 0; j < R; j++)
        STATE[j] = init[j];
}

double WELLRNG512a(void){
    z0 = VRm1;
    z1 = MAT0NEG(-16, V0) ^ MAT0NEG(-15, VM1);
    z2 = MAT0POS(11, VM2);
    newV1 = z1                  ^ z2;
    newV0 = MAT0NEG(-2, z0) ^ MAT0NEG(-18, z1) ^ MAT3NEG(-28, z2) ^ MAT4NEG(-5, 0xda442d24U, newV1);
    state_i = (state_i + 15) & 0x0000000fU;
    return ((double)STATE[state_i]) * FACT;
}

int RANDOM(int from, int to)
{
    if (from > to)
    {
        int tmp = from;
        from = to;
        to = tmp;
    }

    return to + (from - to) * (WELLRNG512a() / (long double)m);
}
#定义m(无符号长)2147483647
#定义w32
#定义r16
#定义p0
#定义m113
#定义M2 9
#定义M3 5
#定义MAT0POS(t,v)(v^(v>>t))
#像这样定义MAT0NEG(t,v)(v^(v)用户515430

#define m  (unsigned long)2147483647

#define W 32
#define R 16
#define P 0
#define M1 13
#define M2 9
#define M3 5

#define MAT0POS(t,v) (v^(v>>t))
#define MAT0NEG(t,v) (v^(v<<(-(t))))
#define MAT3NEG(t,v) (v<<(-(t)))
#define MAT4NEG(t,b,v) (v ^ ((v<<(-(t))) & b))

#define V0            STATE[state_i                   ]
#define VM1           STATE[(state_i+M1) & 0x0000000fU]
#define VM2           STATE[(state_i+M2) & 0x0000000fU]
#define VM3           STATE[(state_i+M3) & 0x0000000fU]
#define VRm1          STATE[(state_i+15) & 0x0000000fU]
#define VRm2          STATE[(state_i+14) & 0x0000000fU]
#define newV0         STATE[(state_i+15) & 0x0000000fU]
#define newV1         STATE[state_i                 ]
#define newVRm1       STATE[(state_i+14) & 0x0000000fU]

#define FACT 2.32830643653869628906e-10

static unsigned int state_i = 0;
static unsigned int STATE[R];
static unsigned int z0, z1, z2;

void InitWELLRNG512a(unsigned int *init){
    int j;
    state_i = 0;
    for (j = 0; j < R; j++)
        STATE[j] = init[j];
}

double WELLRNG512a(void){
    z0 = VRm1;
    z1 = MAT0NEG(-16, V0) ^ MAT0NEG(-15, VM1);
    z2 = MAT0POS(11, VM2);
    newV1 = z1                  ^ z2;
    newV0 = MAT0NEG(-2, z0) ^ MAT0NEG(-18, z1) ^ MAT3NEG(-28, z2) ^ MAT4NEG(-5, 0xda442d24U, newV1);
    state_i = (state_i + 15) & 0x0000000fU;
    return ((double)STATE[state_i]) * FACT;
}

int RANDOM(int from, int to)
{
    if (from > to)
    {
        int tmp = from;
        from = to;
        to = tmp;
    }

    return to + (from - to) * (WELLRNG512a() / (long double)m);
}
#定义m(无符号长)2147483647
#定义w32
#定义r16
#定义p0
#定义m113
#定义M2 9
#定义M3 5
#定义MAT0POS(t,v)(v^(v>>t))

#定义MAT0NEG(t,v)(v^(v这里是一个完整的示例。它没有您可能需要的所有提示。例如,没有默认构造函数,或者一个单词的构造函数。我将此作为练习

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <numeric>
#include <ostream>
#include <random>
#include <vector>

class seed_seq
{
public:
    template <typename InputIterator>
    seed_seq(InputIterator first, InputIterator last)
    {
        for (; first != last; ++first)
        {
            v.push_back(*first);
        }
    }

    template <typename RandomAccessIterator>
    void generate(RandomAccessIterator first, RandomAccessIterator last)
    {
        std::vector<unsigned int>::size_type i = 0;
        for (; first != last; ++first)
        {
            *first = v[i];
            if (++i == v.size()){ i = 0; }
        }
    }

private:
    std::vector<unsigned int> v;
};

class well512
{
public:
    using result_type = unsigned int;

    static result_type min() { return 0; }
    static result_type max() { return std::numeric_limits<std::uint32_t>::max(); }

    static const unsigned int state_size = 16;

    explicit well512(seed_seq& sequence) : index(0)
    { sequence.generate(std::begin(state), std::end(state)); }

    result_type operator()()
    {
        std::uint32_t z0 = state[(index + 15) & 0x0fU];
        std::uint32_t z1 = xsl(16, state[index]) ^ xsl(15, state[(index + 13) & 0x0fU]);
        std::uint32_t z2 = xsr(11, state[(index + 9) & 0x0fU]);
        state[index] = z1 ^ z2;
        std::uint32_t t = xslm(5, 0xda442d24U, state[index]);
        index = (index + state_size - 1) & 0x0fU;
        state[index] = xsl(2, z0) ^ xsl(18, z1) ^ (z2 << 28) ^ t;

        return state[index];
    }

private:
    // xor-shift-right
    std::uint32_t xsr(unsigned int shift, std::uint32_t value)
    { return value ^ (value >> shift); }

    // xor-shift-left
    std::uint32_t xsl(unsigned int shift, std::uint32_t value)
    { return value ^ (value << shift); }

    // xor-shift-left and mask
    std::uint32_t xslm(unsigned int shift, std::uint32_t mask, std::uint32_t value)
    { return value ^ ((value << shift) & mask); }

    unsigned int index;
    std::array<std::uint32_t, state_size> state;
};

int main()
{
    // Use a random device to generate 16 random words used as seed for the well512 engine
    std::random_device rd;

    std::vector<well512::result_type> seed_data;
    std::generate_n(std::back_inserter(seed_data), well512::state_size, std::ref(rd));

    seed_seq sequence(std::begin(seed_data), std::end(seed_data));

    // Create a well512 engine
    well512 engine(sequence);

    // Now apply it like any other random engine in C++11
    std::uniform_int_distribution<> dist{ 1, 6 };
    auto rand = std::function <int()> { std::bind(std::ref(dist), std::ref(engine)) };

    // Print out some random numbers between 1 and 6 (simulating throwing a dice)
    const int n = 100;
    std::generate_n(std::ostream_iterator<int>(std::cout, " "), n, rand);
    std::cout << std::endl;

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类种子
{
公众:
模板
种子顺序(先输入后输入)
{
for(;first!=last;++first)
{
v、 向后推(*第一);
}
}
模板
void generate(首先是RandomAccessIterator,最后是RandomAccessIterator)
{
std::vector::size_type i=0;
for(;first!=last;++first)
{
*第一个=v[i];
如果(++i==v.size()){i=0;}
}
}
私人:
std::向量v;
};
班井512
{
公众:
使用结果类型=无符号整数;
静态结果_type min(){return 0;}
静态结果_type max(){return std::numeric_limits::max();}
静态常量无符号整数状态_size=16;
显式井512(种子顺序和序列):索引(0)
{sequence.generate(std::begin(state),std::end(state));}
结果类型运算符()
{
标准:uint32_t z0=状态[(索引+15)和0x0fU];
std::uint32_t z1=xsl(16,状态[index])^xsl(15,状态[index+13]和0x0fU]);
std::uint32_t z2=xsr(11,状态[(索引+9)和0x0fU]);
状态[索引]=z1^z2;
std::uint32_t=xslm(50xda442d24u,state[index]);
索引=(索引+状态大小-1)&0x0fU;
state[index]=xsl(2,z0)^xsl(18,z1)^(z2>shift);}
//异或左移
std::uint32_t xsl(无符号整数移位,std::uint32_t值)

{return value^(value这里是一个完整的示例。它没有您可能需要的所有提示。例如,没有默认构造函数,或者一个单词的构造函数。我将此作为练习

#include <algorithm>
#include <array>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <numeric>
#include <ostream>
#include <random>
#include <vector>

class seed_seq
{
public:
    template <typename InputIterator>
    seed_seq(InputIterator first, InputIterator last)
    {
        for (; first != last; ++first)
        {
            v.push_back(*first);
        }
    }

    template <typename RandomAccessIterator>
    void generate(RandomAccessIterator first, RandomAccessIterator last)
    {
        std::vector<unsigned int>::size_type i = 0;
        for (; first != last; ++first)
        {
            *first = v[i];
            if (++i == v.size()){ i = 0; }
        }
    }

private:
    std::vector<unsigned int> v;
};

class well512
{
public:
    using result_type = unsigned int;

    static result_type min() { return 0; }
    static result_type max() { return std::numeric_limits<std::uint32_t>::max(); }

    static const unsigned int state_size = 16;

    explicit well512(seed_seq& sequence) : index(0)
    { sequence.generate(std::begin(state), std::end(state)); }

    result_type operator()()
    {
        std::uint32_t z0 = state[(index + 15) & 0x0fU];
        std::uint32_t z1 = xsl(16, state[index]) ^ xsl(15, state[(index + 13) & 0x0fU]);
        std::uint32_t z2 = xsr(11, state[(index + 9) & 0x0fU]);
        state[index] = z1 ^ z2;
        std::uint32_t t = xslm(5, 0xda442d24U, state[index]);
        index = (index + state_size - 1) & 0x0fU;
        state[index] = xsl(2, z0) ^ xsl(18, z1) ^ (z2 << 28) ^ t;

        return state[index];
    }

private:
    // xor-shift-right
    std::uint32_t xsr(unsigned int shift, std::uint32_t value)
    { return value ^ (value >> shift); }

    // xor-shift-left
    std::uint32_t xsl(unsigned int shift, std::uint32_t value)
    { return value ^ (value << shift); }

    // xor-shift-left and mask
    std::uint32_t xslm(unsigned int shift, std::uint32_t mask, std::uint32_t value)
    { return value ^ ((value << shift) & mask); }

    unsigned int index;
    std::array<std::uint32_t, state_size> state;
};

int main()
{
    // Use a random device to generate 16 random words used as seed for the well512 engine
    std::random_device rd;

    std::vector<well512::result_type> seed_data;
    std::generate_n(std::back_inserter(seed_data), well512::state_size, std::ref(rd));

    seed_seq sequence(std::begin(seed_data), std::end(seed_data));

    // Create a well512 engine
    well512 engine(sequence);

    // Now apply it like any other random engine in C++11
    std::uniform_int_distribution<> dist{ 1, 6 };
    auto rand = std::function <int()> { std::bind(std::ref(dist), std::ref(engine)) };

    // Print out some random numbers between 1 and 6 (simulating throwing a dice)
    const int n = 100;
    std::generate_n(std::ostream_iterator<int>(std::cout, " "), n, rand);
    std::cout << std::endl;

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类种子
{
公众:
模板
种子顺序(先输入后输入)
{
for(;first!=last;++first)
{
v、 向后推(*第一);
}
}
模板
void generate(首先是RandomAccessIterator,最后是RandomAccessIterator)
{
std::vector::size_type i=0;
for(;first!=last;++first)
{
*第一个=v[i];
如果(++i==v.size()){i=0;}
}
}
私人:
std::向量v;
};
班井512
{
公众:
使用结果类型=无符号整数;
静态结果_type min(){return 0;}
静态结果_type max(){return std::numeric_limits::max();}
静态常量无符号整数状态_size=16;
显式井512(种子顺序和序列):索引(0)
{sequence.generate(std::begin(state),std::end(state));}
结果类型运算符()
{
标准:uint32_t z0=状态[(索引+15)和0x0fU];
std::uint32_t z1=xsl(16,状态[index])^xsl(15,状态[index+13]和0x0fU]);
std::uint32_t z2=xsr(11,状态[(索引+9)和0x0fU]);