I am trying to implement a PRNG I found online yet I am having compile time issues (seen below):
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'
This is my code:
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 ) );
}
And this is the code I got online...
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;
}
};
Is there any reason this isn't working? How come? Compiling using Visual Studio 2017.
The requirements for a random engine are outlined at [rand.req.eng]; you can find here a summary of them; in particular you are missing (highlighted through the code with a MISSING
comment):
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;
}
};
User contributions licensed under CC BY-SA 3.0