samedi 4 décembre 2021

C++ std::linear_congruential_engine<> Produces Same First Number Regardless of Seed

I am using the C++11 std::linear_congruential_engine<> and am finding that the first number generated by a uniform distribution using this engine is always the same regardless of the seed.

OS and compiler version:

  • CentOS 8.4.2105
  • g++ 8.41

Build command:

g++ -std=c++17 -Wall -Wextra -Wpedantic -Ofast -o test_rand test_rand.cpp

Source code is as follows:

// test_rand.cpp

#include <iostream>
#include <random>

using namespace std;

using my_int_t = long long int;
using my_uint_t = unsigned long long int;

// Same as std::minstd_rand0, except instantiated with unsigned long long int
// rather than unsigned long int
using my_lcg_t = linear_congruential_engine<
                                              my_uint_t,
                                              16807ULL,
                                              0ULL,
                                              2147483647ULL
                                           >;

int main()
{
   my_lcg_t lcg;
   uniform_int_distribution<my_int_t> di{-5LL, 5LL};

   for (my_uint_t seed{1ULL}; seed <= 5ULL; ++seed)
   {
      lcg.seed(seed);

      for (my_uint_t j{0ULL}; j < 3ULL; ++j)
      {
         cout << "seed=" << seed
              << ", output " << j << ": " << di(lcg)
              << endl;
      }

      cout << endl;
   }
}

This program produces the following output:

$ test_rand
seed=1, output 0: -5
seed=1, output 1: -4
seed=1, output 2: 3

seed=2, output 0: -5
seed=2, output 1: -3
seed=2, output 2: 0

seed=3, output 0: -5
seed=3, output 1: -1
seed=3, output 2: -3

seed=4, output 0: -5
seed=4, output 1: 0
seed=4, output 2: -5

seed=5, output 0: -5
seed=5, output 1: 2
seed=5, output 2: 3

The first seed for which -5 is not the first number returned is 11616.

I can try using different parameters for the engine or a different engine type altogether. Or I could discard() the first value. In any case, the question remains...

Why is the first value returned always the same?

Is this inherent in the linear congruential engine? Is it a library bug? Something else?

Aucun commentaire:

Enregistrer un commentaire