Проблема в дополнении. rand()
возвращает int
значение 0...RAND_MAX
. Итак, если вы добавите два из них, вы получите до RAND_MAX * 2
. Если это превышает INT_MAX
, результат сложения переполняет допустимый диапазон, который int
может содержать. Переполнение значений со знаком является неопределенным поведением и может привести к тому, что ваша клавиатура разговаривает с вами на иностранных языках.
Поскольку здесь нет никакого смысла в добавлении двух случайных результатов, простая идея - просто не делать этого. В качестве альтернативы вы можете разыграть каждый результат 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
, что верно для всех реализаций, о которых я знаю (которые охватывают довольно много встроенных архитектур, DSP и всех настольных, мобильных и серверных платформ последних 30 лет).
Предупреждение:
Хотя здесь уже добавлены комментарии, обратите внимание, что при добавлении двух случайных значений не получается равномерное распределение, а треугольное распределение, например, бросание двух кубиков: чтобы получить 12
(два кубика), нужно показать оба кубика 6
. поскольку 11
уже есть два возможных варианта: 6 + 5
или 5 + 6
и т. д.
Таким образом, дополнение также плохо с этой стороны.
Также обратите внимание, что rand()
генерируемые результаты не являются независимыми друг от друга, так как они генерируются генератором псевдослучайных чисел . Отметим также, что в стандарте не указывается качество или равномерное распределение рассчитанных значений.
rand()
не может быть отрицательным ...