Почему rand()% 7 всегда возвращает 0?

Кажется, это действительно странная проблема:

Это мой код:

#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
    @autoreleasepool {
        srand((unsigned int)time(NULL));
        int newRandomNumber = 0;
        newRandomNumber = rand() % 7;
        NSLog(@"%d", rand() % 7); //This prints out what I expected
        NSLog(@"newRandomNumber = %d", newRandomNumber); // This always prints out 0!
    }
    return 0;
}

Если я заменю одну строку, в которой говорится

newRandomNumber = rand() % 7

с

newRandomNumber = rand() % 8

все работает отлично. Почему это так?

Ответ 1

Ну, это

int seed;
for(seed = 1; seed < 10; seed++) {
    srand(seed);
    printf("%4d %16d\n", seed, rand());
}

печатает

   1            16807
   2            33614
   3            50421
   4            67228
   5            84035
   6           100842
   7           117649
   8           134456
   9           151263

что заставляет меня думать, что rand() = seed * 16807

Статья в Википедии Линейный конгруэнтный генератор подтверждает, что CarbonLib действительно использует Xn + 1 = Xn * 16807 для генерации случайных чисел.

Ответ 2

Кажется маловероятным, но выполнение некоторых тестов, после srand первый rand, кажется, всегда делится на 7, по крайней мере, в переменной размера int.

На нескольких прогонах я получил 1303562743, 2119476443 и 2120232758, все из которых от 7 до 0.

Второй rand() работает, потому что это второй rand(). Бросьте rand() до вашего первого rand()... или еще лучше, используйте лучший генератор случайных чисел random или arc4rand, если он доступен.

Также см. вопрос о переполнении стека Почему (rand()% anything) всегда 0 в С++?.