Генерация случайных целых чисел с определенным максимумом
Я хочу генерировать одинаковые целые числа, которые удовлетворяют0 <= result <= maxValue
.
У меня уже есть генератор, который возвращает однородные значения во всем диапазоне встроенных целочисленных типов без знака. Давайте назовем методы для этогоbyte Byte()
, ushort UInt16()
, uint UInt32()
а такжеulong UInt64()
, Предположим, что результат этих методовв совершенстве равномерная.
Подпись методов, которые я хочуuint UniformUInt(uint maxValue)
а такжеulong UniformUInt(ulong maxValue)
.
Что я ищу:
правильностьЯ бы предпочел, чтобы возвращаемые значения были распределены в заданном интервале.
Ноочень допустимо небольшое смещение, если оно значительно повышает производительность. Под этим я подразумеваю смещение порядка, позволяющего различать с вероятностью 2/3 при 2 ^ 64 значениях.
Он должен работать правильно для любого
maxValue
.ПредставлениеМетод должен быть быстрым.КПД
Метод действительно использует небольшую необработанную случайность, поскольку в зависимости от базового генератора генерация необработанных байтов может быть дорогостоящей. Потеря нескольких битов - это хорошо, но, скажем, использование 128 битов для генерации одного числа является чрезмерным.
Также возможно кэшировать некоторую оставшуюся случайность из предыдущего вызова в некоторых переменных-членах.
Будьте осторожны с переполнением int и поведением обёртывания.
У меня уже есть решение (я опубликую это как ответ), но это немного уродливо для моих вкусов. Поэтому я хотел бы получить идеи для лучших решений.
Предложения о том, как провести модульное тестирование с большимиmaxValue
Было бы неплохо, поскольку я не могу сгенерировать гистограмму с 2 ^ 64 сегментами и 2 ^ 74 случайными значениями. Другое осложнение заключается в том, что с некоторыми ошибками, только некоторыеmaxValue
дистрибутивы сильно смещены, а другие лишь незначительно.