Как я могу избавиться от предупреждения с помощью rand()?(С++)

StackOverflow https://stackoverflow.com/questions/817975

Вопрос

Всякий раз, когда я использую функцию rand в C++:

#include<iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
int main(){
srand(time(0));
int n=(rand()%6)+1;
cout<<"The dice roll is "<<n<<"."<<endl;
}

Я получаю предупреждение о преобразовании из time_t в int в строке 5:

srand(time(0));

Есть ли способ избавиться от этого предупреждения?

Это было полезно?

Решение

На самом деле вы должны использовать unsigned int с srand () :

srand((unsigned) time(0));

Другие советы

В другом примечании этот код:

rand()%6

обычно рассматривается как плохая практика.младшие биты rand() значительно менее случайны, чем старшие биты.Вы получите лучшую случайность, если сделаете:

(rand() >> 8)%6

например.

РЕДАКТИРОВАТЬ:

Более подробно об этом см. эта заметка а также эта статья из ДокторДоббс журнал, который хотя бы намекает на причину:

Примечание:Не использовать

  y = rand()  %  M;

Поскольку это фокусируется на нижних битах rand ().Для линейных генераторов случайных чисел, которые часто бывают, более низкие байты гораздо менее случайны, чем более высокие байты.На самом деле самые низкие циклы от 0 до 1.Таким образом, rand () может ездить на велосипеде между ровным и нечетным (попробуйте).Примечание rand () не обязательно должен быть линейным генератором случайных чисел.Это совершенно допустимо, чтобы это было чем -то лучшим, у которого нет этой проблемы.

ДДДЖ:

Наиболее важным моментом является то, что более низкие биты вывода от обычных (линейных конгруэнтных) генераторов случайных чисел являются наименьшими «случайными». То есть закономерности в более низких битах распространены.Следовательно, вывод рутинного броска в вашем обсуждении не удивителен.Кроме того, его можно избежать, полагаясь на верхние биты, чтобы определить возвращение целого числа.

Например, если вы хотите выбрать случайное значение «истина» или «ложь» и использовали код:

rand() % 2

Тогда вы можете увидеть картину результатов:

1,0,1,0,1,0,1,0,1,0 (и т. д.)

Очевидно, это не так уж и случайно, но это свойство линейного конгруэнтного генератора, который может использоваться.Лучшей схемой (для C++) могло бы быть использование Boost.Случайный библиотека, которая поддерживает все виды подключаемых генераторов случайных чисел (включая Mersenne Twister, у которого нет этого недостатка).

Используйте явное приведение, чтобы избавиться от предупреждения:

srand((int)time(0));

Два боковых примечания:

  • Стандартный способ включения заголовков C в C++ выглядит следующим образом: #include <cstdio>.
  • Параметр, переданный в time() это указатель, и многие люди думают, что NULL является более читаемым нулевым указателем, чем 0.

Чтобы избавиться от предупреждения, вы должны использовать статическое приведение к целому без знака.

srand(static_cast<unsigned int>(time(0)));

В соответствующем примечании результаты rand должны быть сдвинуты вправо, чтобы устранить смещение младших битов.

int n = ((rand() >> 8) % 6) + 1;

Наконец, в C ++ время C и стандартные библиотеки должны быть включены как:

#include <ctime>
#include <cstdlib>

Это поместит функции в соответствующее пространство имен 'std'.

Также,

 rand() % 6

внесет небольшой уклон.Поскольку RAND_MAX % 6 равен 1, ноль и единица будут появляться немного чаще, чем от двух до шести.В этом случае они будут возвращены 5462 раза на каждые 5461 раз, когда будут возвращены более высокие числа, так что вы, вероятно, этого не заметите.Однако если диапазон желаемых чисел велик, смещение может быть значительным.Например, если вы сделали rand() % 32000, то числа в диапазоне 0–767 будут встречаться в два раза чаще, чем числа 768–32000.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top