【问题标题】:Using a public PRNG and uniform distribution (C++17)使用公共 PRNG 和均匀分布 (C++17)
【发布时间】:2018-11-11 13:10:13
【问题描述】:

我正在尝试实现我在网上找到的 PRNG,但我遇到了编译时问题(见下文):

1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xutility(4010): error C2061: syntax error: identifier 'result_type'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xutility(4012): error C2065: '_Ty1': undeclared identifier
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xutility(4012): error C2065: '_Ty1': undeclared identifier
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\xutility(4012): error C2923: 'std::conditional_t': '_Ty1' is not a valid template type argument for parameter '_Ty2'

这是我的代码:

std::random_device rd;
small_prng engine;
std::uniform_int_distribution< int > ud( 0, 50 );

for ( auto i = 0; i < 100; i++ ) {
    printf( "%i\n", ud( engine ) );
}

这是我上网的代码……

class small_prng {
    uint32_t a;
    uint32_t b;
    uint32_t c;
    uint32_t d;

    static inline uint32_t rot( uint32_t x, uint32_t k ) noexcept {
        return ( ( ( x ) << ( k ) ) | ( ( x ) >> ( 32 - ( k ) ) ) );
    }
public:
    using value_type = uint32_t;

    explicit small_prng( uint32_t seed = 0xdeadbeef ) noexcept {
        a = 0xf1ea5eed;
        b = c = d = seed;
        for ( size_t i = 0; i < 20; ++i )
            ( *this )( );
    }

    inline uint32_t operator()( ) noexcept {
        uint32_t e = a - rot( b, 27 );
        a = b ^ rot( c, 17 );
        b = c + d;
        c = d + e;
        d = e + a;
        return d;
    }
};

这不起作用有什么原因吗?怎么会?使用 Visual Studio 2017 编译。

【问题讨论】:

  • 类定义在哪里?
  • 道歉@MatteoItalia 现在添加了它。
  • @BasileStarynkevitch 我不想......我这样做的全部原因是为了性能。
  • 您进行了基准测试吗? Mersenne Twister 跑得很快

标签: c++ visual-studio random visual-studio-2017


【解决方案1】:

[rand.req.eng] 中概述了随机引擎的要求; you can find here a summary of them;特别是您缺少(通过带有MISSING 注释的代码突出显示):

class small_prng {
    uint32_t a;
    uint32_t b;
    uint32_t c;
    uint32_t d;

    static inline uint32_t rot( uint32_t x, uint32_t k ) noexcept {
        return ( ( ( x ) << ( k ) ) | ( ( x ) >> ( 32 - ( k ) ) ) );
    }
public:
    // MISSING: the result type must indeed be called `result_type`
    using result_type = uint32_t;

    // MISSING: you must provide min and max, with the
    // minimum/maximum value your RNG can return
    result_type min() const noexcept { return 0; }
    result_type max() const noexcept { return 0xffffffff; }

    explicit small_prng( result_type seed = 0xdeadbeef ) noexcept {
        a = 0xf1ea5eed;
        b = c = d = seed;
        for ( size_t i = 0; i < 20; ++i )
            ( *this )( );
    }

    // MISSING: constructor from a SeedSequence (see https://en.cppreference.com/w/cpp/named_req/SeedSequence)
    template<typename S>
    explicit small_prng(S &seq) {
        uint32_t nseed[1];
        seq.generate(nseed, nseed+1);
        seed(nseed[0]);
    }

    // MISSING: seed() overloads
    void seed() { *this = small_prng(); }
    void seed(result_type seed) { *this = small_prng(seed); }
    template<typename S> void seed(S &seq) { *this = small_prng(seq); }

    inline result_type operator()( ) noexcept {
        uint32_t e = a - rot( b, 27 );
        a = b ^ rot( c, 17 );
        b = c + d;
        c = d + e;
        d = e + a;
        return d;
    }

    // MISSING: discard n extractions
    void discard(unsigned long long z) {
        // does this engine implement more efficient jump-ahead?
        while(z--) (*this)();
    }

    // MISSING: dump generator state operator
    friend std::ostream &operator<<(std::ostream &os, const small_prng &r) {
        return os<<r.a<<" "<<r.b<<" "<<r.c<<" "<<r.d<<" ";
    }

    // MISSING: read from generator state dump operator
    friend std::istream &operator>>(std::istream &is, small_prng &r) {
        return is>>r.a>>r.b>>r.c>>r.d;
    }
};

【讨论】:

  • 序列构造函数调用是否正确? This 建议参数应该表示要写入的范围。
猜你喜欢
  • 2011-09-16
  • 2012-07-10
  • 2014-10-24
  • 2011-04-04
  • 2021-12-28
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多