Подтвердить что ты не робот

Rand() между 0 и 1

Таким образом, следующий код делает 0 < r < 1

r = ((double) rand() / (RAND_MAX))

Почему создание r = ((double) rand() / (RAND_MAX + 1)) делает -1 < r < 0?

Не следует добавлять одно к RAND_MAX, чтобы сделать 1 < r < 2?

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

на этой строке, так что это может быть проблемой. Я просто сделал cout << r << endl, и он определенно дает мне значения между -1 и 0

4b9b3361

Ответ 1

Это полностью специфичный для реализации, но похоже, что в среде С++, в которой вы работаете, RAND_MAX равно INT_MAX.

Из-за этого RAND_MAX + 1 демонстрирует поведение undefined (переполнение) и становится INT_MIN. В то время как ваш начальный оператор делялся (случайным образом # между 0 и INT_MAX)/(INT_MAX) и генерировал значение 0 <= r < 1, теперь он делит (случайный # между 0 и INT_MAX)/(INT_MIN), генерируя значение -1 < r <= 0

Чтобы создать случайное число 1 <= r < 2, вам нужно

r = ((double) rand() / (RAND_MAX)) + 1

Ответ 2

Нет, поскольку RAND_MAX обычно расширяется до MAX_INT. Поэтому добавление одного (по-видимому) помещает его в MIN_INT (хотя это должно быть поведение undefined, как я сказал), следовательно, обращение знака.

Чтобы получить то, что вы хотите, вам нужно будет переместить +1 за пределы вычислений:

r = ((double) rand() / (RAND_MAX)) + 1;

Ответ 3

rand() / double(RAND_MAX) генерирует случайное число с плавающей запятой между 0 (включительно) и 1 (включительно), но это не очень хорошо по следующим причинам (поскольку RAND_MAX обычно 32767):

  • Количество различных случайных чисел, которые могут быть сгенерированы, слишком мало: 32768. Если вам нужны более разные случайные числа, вам нужен другой способ (пример кода приведен ниже)
  • Сгенерированные числа слишком грубые: вы можете получить 1/32768, 2/32768, 3/32768, но никогда ничего между ними не было.
  • Ограниченные состояния двигателя генератора случайных чисел: после генерации случайных чисел RAND_MAX реализации обычно начинают повторять одну и ту же последовательность случайных чисел.

Из-за вышеуказанных ограничений rand() лучший выбор для генерации случайных чисел между 0 (включительно) и 1 (эксклюзивный) был бы следующим фрагментом (похожим на пример в http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution):

#include <iostream>
#include <random>
#include <chrono>

int main()
{
    std::mt19937_64 rng;
    // initialize the random number generator with time-dependent seed
    uint64_t timeSeed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
    std::seed_seq ss{uint32_t(timeSeed & 0xffffffff), uint32_t(timeSeed>>32)};
    rng.seed(ss);
    // initialize a uniform distribution between 0 and 1
    std::uniform_real_distribution<double> unif(0, 1);
    // ready to generate random numbers
    const int nSimulations = 10;
    for (int i = 0; i < nSimulations; i++)
    {
        double currentRandomNumber = unif(rng);
        std::cout << currentRandomNumber << std::endl;
    }
    return 0;
}

Это легко изменить для генерации случайных чисел между 1 (включительно) и 2 (эксклюзивным), заменив unif(0, 1) на unif(1, 2).

Ответ 4

Это не так. Он делает 0 <= r < 1, но ваш оригинал 0 <= r <= 1.

Обратите внимание, что это может привести к undefined поведению, если RAND_MAX + 1 переполняется.

Ответ 5

Я предполагаю, что RAND_MAX равен INT_MAX, и поэтому вы переполняете его на отрицательный.

Просто сделайте следующее:

r = ((double) rand() / (RAND_MAX)) + 1;

Или даже лучше, используйте генераторы случайных чисел С++ 11.

Ответ 6

Это правильный путь:

double randd() {
  return (double)rand() / ((double)RAND_MAX + 1);
}

или

double randd() {
  return (double)rand() / (RAND_MAX + 1.0);
}