Чтобы не забыть и впоследствии освежить память
Для генерации случайных чисел используется стандартная функция, которая генерирует случайные числа в С — rand() ;
Для получения отрицательных случайных чисел, например от -10 до 10, можно использовать вот такой код
Для получения любого диапазона случайных чисел A до B, можно использовать вот такой код
У меня есть этот кусочек кода при попытке создать случайное число между n и n ^ 2, и иногда он дает отрицательное число. Я проверил rand() а также time(NULL) и оба они производят положительное число, так как может быть возможно, чтобы в результате получилось отрицательное число?
Я предполагаю генерировать много чисел для хранения в массиве, но почему-то только первые несколько чисел являются отрицательными.
Решение
Целочисленное переполнение. time(NULL) в настоящее время возвращает значение около 1,49 млрд. Умножая это на rand() переполнится практически на любом значении rand() и приведет к отрицательному значению примерно в половине случаев.
Не умножьте на time(NULL) , Это не имеет смысла здесь. Просто используйте rand() ,
Другие решения
Что вы хотите сделать, это семя генератор случайных чисел один раз со временем
После этого вызывайте функцию без вовлечения времени
Повторное заполнение генератора случайных чисел — плохая идея, особенно со временем. В C ++ 11 есть лучшие способы сделать это с std::random ,
Я хотел бы добавить к ответ дано Разиман Т В . Если вы пишете на C ++ 11, то я настоятельно рекомендую использовать новые «генераторы» и «дистрибутивы». «Генераторы» заменяют «rand ()» и позволяют генерировать псевдослучайные числа, которые распределены равномерно (например, «rand ()»). «Распределения» преобразуют последовательность сгенерированных чисел в соответствии с заданным распределением (равномерное, нормальное, Вейбулла и т. Д.). Больше информации можно найти Вот .
Вот пример того, как вы можете генерировать псевдослучайные числа в диапазоне [10; 20]:
Основное преимущество заключается в том, что вы можете использовать произвольное количество генераторов (инициализированных с разными начальными значениями) и распределений для генерации разных псевдослучайных последовательностей. Было бы сложно создать две разные последовательности одновременно с помощью ‘rand ()’.
Я заметил, что функция библиотеки rand() , когда она вызывается только один раз в цикле, она почти всегда производит положительные числа.
Но когда я добавляю два вызова rand() , генерируемые числа теперь имеют больше отрицательных чисел.
Может кто-нибудь объяснить, почему во втором случае я вижу отрицательные числа?
PS: Я инициализирую семя перед циклом как srand(time(NULL)) .
rand() определено для возврата целого числа между 0 и RAND_MAX .
может переполняться. То, что вы наблюдаете, вероятно, является результатом undefined поведения, вызванного переполнением целых чисел.
Проблема заключается в добавлении. rand() возвращает значение int 0. RAND_MAX . Итак, если вы добавите два из них, вы получите до RAND_MAX * 2 . Если это превышает INT_MAX , результат добавления переполняет допустимый диапазон, который может содержать int . Переполнение значных значений undefined и может привести к тому, что ваша клавиатура будет разговаривать с вами на иностранных языках.
Поскольку здесь нет выигрыша при добавлении двух случайных результатов, простая идея состоит в том, чтобы просто не делать этого. В качестве альтернативы вы можете сделать каждый результат до unsigned int до добавления, если это может удерживать сумму. Или используйте больший тип. Обратите внимание, что long не обязательно шире, чем int , то же самое относится к long long , если int не менее 64 бит!
Заключение: просто избегайте добавления. Это не дает больше "случайности". Если вам нужно больше битов, вы можете объединить значения sum = a + b * (RAND_MAX + 1) , но для этого, вероятно, также потребуется больший тип данных, чем int .
Как ваша заявленная причина состоит в том, чтобы избежать нулевого результата: этого нельзя избежать, добавив результаты двух вызовов rand() , так как оба могут быть равны нулю. Вместо этого вы можете просто увеличить. Если RAND_MAX == INT_MAX , это невозможно сделать в int . Однако (unsigned int)rand() + 1 сделает очень, очень вероятно. Вероятно (не окончательно), потому что он требует UINT_MAX > INT_MAX , который я не уверен, гарантирован, но действителен для всех реализаций, о которых я действительно знаю (и это не просто x86/64 или ARM).
Внимание:
Несмотря на то, что здесь уже посыпаны комментарии, обратите внимание, что добавление двух случайных значений не получает равномерного распределения, но треугольное распределение, например, перекатывание двух кубиков: чтобы получить 12 (две кости), обе кости должны показать 6 , для 11 уже есть два возможных варианта: 6 + 5 или 5 + 6 и т.д.
Таким образом, добавление также плохо из этого аспекта.
Также обратите внимание, что генерируемые результаты rand() не являются независимыми друг от друга, поскольку они генерируются генератором псевдослучайных чисел . Отметим также, что стандарт не определяет качество или равномерное распределение вычисленных значений.