Why does the following C code give me different results on my desktop and server, both work with similar versions of Linux?
He finds the longest same side in a string sequence of 18 trillion coin tosses. [Cm. The science fiction novel by Ian M. Banks. Consider Phlebas.]
On the server, after 15.7 trillion coin tones (it still works), the longest same side in the string sequence is still 29. Since 2^44 = 17,592,186,044,416 , I expect the longest same sequence to be somewhere in the middle 40s and probably 44 after completing a total of 18 trillion.
On the desktop, after only 4.7 billion coins were thrown, the longest sequence was already 31, since 2^31 = 2,147,483,648 , and it sounded right.
So, why did I get a sequence of 29 on the server after 15.7 trillion coins, but a sequence of 31 after only 4.7 billion on my desktop?
Module bias was my first thought. RAND_MAX same on both the desktop and the server, 2,147,483,647 (32 bits, signed for a long time). So the rand() function will give me the number 0 <= rand() <= 2,147,483,647 . 0 is equal, and 2,147,483,647 is odd, so if I’m not very mistaken, there is no modulo offset introduced by my line of code int rand_num = (rand() % 2); .
I know that the C standard pseudo-random number generator is not considered sufficient for cryptography. Of course, this could not be a factor in the generation, however, of rather long sequences of zeros and ones. Can it?
Here's the source:
Compiled on both machines using: 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); }