Почему следующий код C дает мне разные результаты на моем рабочем столе и сервере, оба работают с аналогичными версиями Linux?18 трлн монетных монет, где я ошибся?
Он находит самую длинную ту же сторону в последовательности строк в 18 трлн монетных бросков. [См Iain M. банков научной фантастики роман Рассмотрим Флебе.]
На сервере, после того, как 15,7 триллионов бросков монеты (он все еще работает), самую длинную сторону в той же последовательности строк до сих пор только 29. Так как 2^44 = 17,592,186,044,416
, я ожидал бы, что самая длинная такая же последовательность будет находиться где-то в середине до середины 40-х годов, и, вероятно, 44 после завершения всего 18 триллионов.
На рабочем столе после того, как только 4,7 миллиарда монет бросает самую длинную последовательность, было уже 31, с 2^31 = 2,147,483,648
, и это звучало о праве.
Итак, почему я получил последовательность из 29 на сервере после 15,7 трлн монет, но последовательность из 31 после всего лишь 4,7 млрд. На моем рабочем столе?
Modulo bias была моей первой мыслью. RAND_MAX
- это то же самое как на рабочем столе, так и на сервере, 2,147,483,647 (32 бит подписан долго). Таким образом, функция rand()
даст мне номер 0 <= rand() <= 2,147,483,647
. 0 равно и 2,147,483,647 является нечетным, поэтому, если я не очень ошибаюсь, нет никакого модульного смещения, введенного моей линией кода int rand_num = (rand() % 2);
.
Я знаю, что генератор псевдослучайных чисел стандартной библиотеки C не считается достаточным для криптографии. Конечно, это не могло быть фактором при генерации, правда, довольно длинных последовательностей нулей и единиц. Не могли бы?
Вот источник:
Составлено на обеих машинах с использованием: gcc -O3 -o 18TCT 18TrillionCoinTosses.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char* argv[])
{
srand(time(NULL));
int current_seq = 0;
int longest_seq = 0;
int prev_rand_num = -1;
long long i = 0;
long long total = 18000000000000;
// To serve as a rudimentary progress indicator.
long billion_counter = 0;
long billion = 1000000000;
while (i < total)
{
int rand_num = (rand() % 2);
if (rand_num == prev_rand_num)
{
current_seq++;
if (current_seq >= longest_seq)
{
longest_seq = current_seq;
printf("Longest sequence so far: %d (on iteration %lli)\n", longest_seq, i);
}
}
else
current_seq = 1;
if (billion_counter == billion)
{
billion_counter = 0;
printf("Progress report, current iteration: %lli\n", i);
}
prev_rand_num = rand_num;
i++;
billion_counter++;
}
printf("\nTotal coins tossed: %lli\n", i);
printf("Longest sequence: %d\n", longest_seq);
}
TL; DR. Не пиши роман. См. [Ask]. – Olaf
Похоже, что вопрос: «Почему вывод отличается от сервера и ноутбука?» 99% остального - пух. – csmckelvey
честно, мне понравилось читать. – mfro