C #: Random.NextDouble и включая границы пользовательского интервала - PullRequest
4 голосов
/ 28 мая 2011

Я использовал эту формулу для получения случайного двойного числа в произвольном интервале:

Random r = new Random();
double Upper = 3.7, Lower = 11.4, Result;    
Result = Lower + (r.NextDouble() * (Upper - Lower))
// Lower is the lower border of interval, Upper is the upper border of interval

Но помните , что MSDN говорит о методе NextDouble:

Число с плавающей запятой двойной точности больше или равно 0,0 и меньше 1,0.

Это означает, что интервал в моем примере кода будет равен 3,7, но мы никогда не получим 11,4, верно?Как я могу включить верхнюю границу?

Lower + (r.NextDouble() * (Upper - Lower + double.Epsilon))

Может ли эта формула помочь?Или есть другой вариант получения случайных двойных чисел в [3.7;11.4] (включая обе границы)?

Ответы [ 4 ]

3 голосов
/ 28 мая 2011

Вам действительно нужен верхний интервал для двойного регистра?Вероятность достижения именно этого значения действительно очень мала и должна быть статистически незначимой практически для всех сценариев.Если вас интересуют числа с определенным количеством десятичных знаков, то вы можете использовать некоторое округление, чтобы получить то, что вам нужно.

3 голосов
/ 28 мая 2011

Поскольку ваше использование удваивается, какую точность вы на самом деле используете?Округления чисел может быть достаточно.В качестве альтернативы вы можете использовать свое собственное масштабирование, например, так:

static void Main(string[] args)
{
    var r = new Random(3);

    for (int i = 0; i < 100; i++)
    {
        Console.WriteLine(r.NextDouble(0, 1, 100));
    }

    Console.ReadKey();
}

public static double NextDouble(this Random r
    , double lower
    , double upper
    , int scale = int.MaxValue - 1
    )
{
    var d = lower + ((r.Next(scale + 1)) * (upper - lower) / scale);
    return d;
}

Это даст вам нижний и верхний диапазон включения в указанной шкале.Я добавил значение по умолчанию для масштаба, которое дает вам максимально возможную точность, используя этот метод.

1 голос
/ 28 мая 2011

Точность сама по себе является проблемой, так как 3.7 и 11.4 не имеют точного двойного представления.

Я думаю, что, поскольку вы используете случайное число двойной точности, я не думаю, что эта неточность - это то, что нужно заботитьсяо.

0 голосов
/ 28 мая 2011

Добавить следующее

Result = Math.Round(Result, 8)

и вуаля.

Число 8 - это десятичные разряды, до которых оно будет округляться. Когда случайное число находится в пределах 8 десятичных знаков от верхней границы (пример: 11.3999999990), то результат округляется до границы (ответ: 11.4000000000)

Конечно, раунд происходит для всех чисел, поэтому тщательно выбирайте свою точность. Это действительно зависит от приложения, если 8 десятичных знаков это хорошо. Ваш лимит от 1 до 15.

...