Я генерирую много случайных чисел, которые должны быть в диапазоне от 1 до 15 (включены) в C ++.Конечно, я могу генерировать zillons std::uniform_int_distribution<std::mt19937::result_type> random(1, 15);
, но это пустая трата, так как этот твистер mersenn генерирует 32 бита (или даже 64 с использованием mt19937_64) случайных значений, и я бы оставил только 4 бита и выбросил бы все остальные, и вВ моем случае производительность является проблемой, и генерация случайных чисел вносит существенный вклад.
Таким образом, моя идея заключалась в том, чтобы сгенерировать, например, одно 64-битное случайное значение в диапазоне от 0 до 2 ^ 64-1 и выбрать 4 бита.среди них.Проблема в том, что я не могу найти способ сгенерировать значения от 1 до 15. Пример:
unsigned long long int r = uniform(generator); // between 0 and 2^64-1
unsigned int r1 = (r+1)&15; // first desired random value
unsigned int r2 = ((r>>4)+1)&15; //second desired random value
unsigned int r3 = ((r>>8)+1)&15; //third desired random value
...
Здесь эта версия, конечно, не работает: несмотря на +1, сгенерированныйзначения по-прежнему находятся в диапазоне от 0 до 15 (поскольку, если r&15
равно 0xb1111
, то добавление 1 приводит к результату 0xb0000
).
Кроме того, я хотел бы, чтобы распределение оставалось равномерным (например,Мне бы не хотелось, чтобы смещение младшего значащего бита происходило чаще, что может иметь место с чем-то вроде (r&15+1)|((r&15 +1) >> 4)
, поскольку значение 0xb0001
встречается дважды чаще).