Как вы генерируете случайный дубль, равномерно распределенный между 0 и 1 из C ++? - PullRequest
58 голосов
/ 27 августа 2009

Как вы генерируете случайный дубль, равномерно распределенный между 0 и 1 из C ++?

Конечно, я могу придумать некоторые ответы, но я бы хотел знать, что такое стандартная практика:

  • Хорошее соответствие стандартам
  • Хорошая случайность
  • Хорошая скорость

(скорость важнее, чем случайность для моего приложения).

Большое спасибо!

PS: В случае, если это имеет значение, мои целевые платформы - Linux и Windows.

Ответы [ 13 ]

0 голосов
/ 24 августа 2010
double randDouble()
{
  double out;
  out = (double)rand()/(RAND_MAX + 1); //each iteration produces a number in [0, 1)
  out = (rand() + out)/RAND_MAX;
  out = (rand() + out)/RAND_MAX;
  out = (rand() + out)/RAND_MAX;
  out = (rand() + out)/RAND_MAX;
  out = (rand() + out)/RAND_MAX;

  return out;
}

Не так быстро, как double X=((double)rand()/(double)RAND_MAX);, но с лучшим распределением. Этот алгоритм дает только RAND_MAX равномерно распределенный выбор возвращаемых значений; этот дает RANDMAX ^ 6, поэтому его распространение ограничено только точностью double.

Если вы хотите длинный двойной, просто добавьте несколько итераций. Если вам нужно число в [0, 1], а не в [0, 1), просто сделайте в строке 4 чтение out = (double)rand()/(RAND_MAX);.

0 голосов
/ 27 августа 2009

Хорошо учитывая простоту и скорость в качестве основных критериев, вы можете добавить небольшого вспомогательного помощника, например: -

  // C++ rand generates random numbers between 0 and RAND_MAX. This is quite a big range
  // Normally one would want the generated random number within a range to be really
  // useful. So the arguments have default values which can be overridden by the caller
  int nextRandomNum(int low = 0, int high = 100) const {
    int range = (high - low) + 1;
    // this modulo operation does not generate a truly uniformly distributed random number
    // in the span (since in most cases lower numbers are slightly more likely), 
    // but it is generally a good approximation for short spans. Use it if essential
    //int res = ( std::rand() % high + low );
    int res = low + static_cast<int>( ( range * std::rand() / ( RAND_MAX + 1.0) ) );
    return res;
  }

Генерация случайных чисел является хорошо изученной, сложной и сложной темой. Здесь вы можете найти несколько простых, но полезных алгоритмов, помимо тех, которые упомянуты в других ответах: -

Вечная путаница

0 голосов
/ 27 августа 2009

Вы можете попробовать алгоритм Мерсенна Твистера.

http://en.wikipedia.org/wiki/Mersenne_twister

Он имеет хорошее сочетание скорости и случайности, а также реализацию GPL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...