...

суббота, 14 июня 2014 г.

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

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

Все рисунки (рисунок) делал в 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


Резюме



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

This entry passed through the Full-Text RSS service — if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий