Хитрый и китайский рандом или «закон сохранения массы никто не отменял»

от автора

Как известно, функция случайных, псевдо-случайных чисел имеет достаточно высокую битность. Однако никто не знает некоторых ловушек связанные именно с точностью. Я поясню в теории. Дальше (правильнее сказать глубже) думайте сами. Суть в том, что я привожу стандартный двойной рандом и китайский двойной рандом, и не очевидные отличия.

Все рисунки (рисунок) делал в Paint’e.

Суть

Для примера приведу стандартный float/double рандом в диапозоне от 0 до 1 (в нашем случае 1 не включается в набор, поскольку генерирует дробь). Еще у нас доступен набор целочисленных. Так вот. В математике можно просто растянуть умножением. Но в компьютерной реальности лучше этого не делать, а генерировать плотную последовательность как есть. Как это сделать? Правильно: генерировать как минимум два случайных числа. Суть в том, что мы охватывает все возможные точности при генерации случайных чисел в диапазонах (в нашем случае от 0 до N).

Стандартный рандом. Точность такая, какая есть.
random = random()

Двойной рандом. Никто не знает, но это только вредит общей точности случайных чисел.
random = random() * 2.0

Китайский двойной рандом. Не вредит точности, либо вредит не сильно.
random = random() > 0.5 ? random() : random() + 1.0

Немного профессиональнее. Суть в том, что генерирует раздельно целую и дробную часть. Как и китайский брат, не влияет на точность.
random = floor(random() * some_integer) + random()

В чем дело? Дело в том, что в первом случае мы просто «растягиваем» вероятность (* и /). При этом сохраняется опасность при очень больших значениях сильно повредить точность. В остальных случаях генерируется точность для дробной и целой части. При этом можно просто сместить (операция + и -) и обрезать (max, min, clamp). Также можно попробовать сжать делением. Но растягивать умножением последовательность лучше в крайнем случае.

Иллюстрация

Привел более наглядный рисунок. Два или один рандом: решать вам.
image

Резюме

Я привел краткое пояснение по точности случайных чисел. Если для вас производительность не имеет значение, то лучше не тянуть, а заливать.

ссылка на оригинал статьи http://habrahabr.ru/post/226223/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *