u_int32_t maxValue = ~((u_int32_t) 0); // equal to 0xffff...
maxValue -= maxValue % x; // make maxValue a multiple of x
while((value = arc4random()) >= maxValue) { // loop until we get 0 ≤ value < maxValue
}
value %= x;
Несколько педантичное возражение против ответа Коббала. Он «работает», то есть устраняет смещение по модулю, но отклоняет больше значений, чем необходимо. Самый крайний случай x = 2 ^ 31. Все значения arc4random () должны быть приняты здесь, но код, как написано, отклонит половину из них.
Вместо этого, добавьте 1 к инициализации maxValue (который устанавливает его в 2 ^ 32, так что вам придется использовать 64-битное целое число), и тогда это правильно. Вы также можете избежать использования 64-битного int. Проверьте заранее, если 2 ^ 32% x == 0, если так, все значения arc4random () являются приемлемыми, и вы можете пропустить цикл, в противном случае вы можете сохранить значение maxValue в 32 битах, вычитая 2 ^ 32% x при инициализации.