我有很多不同的伪随机数生成器,用C编写,生成任意数量的随机数对(通过CLI),并将它们存储在(新)文本文件中:每列一对数字.我想将400.000.000
数字存储在文本文件中,但是当我查看文件的行数时,它只有82.595.525行.这是代码:
#include#include #include #include "../Calculos/myfunctions.c" void outputDevRandomOpenFile (FILE * from_file, FILE * to_file, unsigned long long how_many_pairs){ unsigned long long i = 0LL; int seed; unsigned long long max_period = 2147483648LL; for (i = 0LL; i < how_many_pairs; i += 1LL){ fread (&seed, sizeof(int), 1, from_file); fprintf (to_file, "%.10lf ", fabs (((double) seed) / ((double) max_period))); fread (&seed, sizeof(int), 1, from_file); fprintf (to_file, "%.10lf\n", fabs (((double) seed) / ((double) max_period))); } } int main (int argc, char *argv[]){ char * endptr; unsigned long long how_many_pairs = (unsigned long long) strtoull (argv[1], &endptr, 10); FILE * urandom = fopen ("/dev/urandom", "r"); FILE * to_file = fopen ("generated_numbers_devrandom.txt", "w"); outputDevRandomOpenFile (urandom, to_file, how_many_pairs); fclose (urandom); return 0; }
起初我怀疑代码中有一些问题(即我可能在某处选择了错误类型的变量),但我通过在for-loop中包含一个来测试它if (i > 165191050) printf ("%llu\n", i);
(提醒我使用的是一维数组)用于存储数字对,而不是二维数,所以在条件中我只是乘以82595525*2
)来测试问题是代码是不是循环800.000.000
次数,而只是165191050
.当我执行测试之后i = 165191050
,它刚开始i
在shell上打印出值,所以它确实循环了那些800.000.000
时间,但是当我查看生成的文本文件的行数时,又有了82595525
一行.所以我打赌问题不在代码中(或者至少不在我使用的变量类型中).
我也用这个算法得到了相同的结果(这只是另一个不同的伪随机数发生器):
#include#include #include #define MT_LEN 624 int mt_index; unsigned long mt_buffer[MT_LEN]; void mt_init() { int i; for (i = 0; i < MT_LEN; i++) mt_buffer[i] = rand(); mt_index = 0; } #define MT_IA 397 #define MT_IB (MT_LEN - MT_IA) #define UPPER_MASK 0x80000000 #define LOWER_MASK 0x7FFFFFFF #define MATRIX_A 0x9908B0DF #define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK) #define MAGIC(s) (((s)&1)*MATRIX_A) unsigned long mt_random() { unsigned long * b = mt_buffer; int idx = mt_index; unsigned long s; int i; if (idx == MT_LEN*sizeof(unsigned long)) { idx = 0; i = 0; for (; i < MT_IB; i++) { s = TWIST(b, i, i+1); b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s); } for (; i < MT_LEN-1; i++) { s = TWIST(b, i, i+1); b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s); } s = TWIST(b, MT_LEN-1, 0); b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s); } mt_index = idx + sizeof(unsigned long); return *(unsigned long *)((unsigned char *)b + idx); /* Here there is a commented out block in MB's original program */ } int main (int argc, char *argv[]){ char * endptr; const unsigned long long how_many_pairs = (unsigned long long) strtoll (argv[1], &endptr, 10); unsigned long long i = 0; FILE * file = fopen ("generated_numbers_mt.txt", "w"); mt_init (); for (i = 0LL; i < how_many_pairs; i++){ fprintf (file, "%.10lf ", ((double) mt_random () / (double) 4294967295)); fprintf (file, "%.10lf\n", ((double) mt_random () / (double) 4294967295)); } fclose (file); return 0; }
它再次循环800.000.000
次数,但它只存储165191050
数字.
$ ./devrandom 400000000 $ nl generated_numbers_devrandom.txt | tail # Here I'm just asking the shell to number the lines of the text file and to print out the 10 last ones. 82595516 0.8182168589 0.0370640513 82595517 0.1133005517 0.8237414290 82595518 0.9035788113 0.6030153367 82595519 0.9192735264 0.0945496135 82595520 0.0542484536 0.7224835437 82595521 0.1827865853 0.9254508596 82595522 0.0249044443 0.1234162976 82595523 0.0371284033 0.8898798078 82595524 0.5977596357 0.9672102989 82595525 0.5523654688 0.29032228
这里发生了什么?
提前致谢.
每行长26个字符,82595525行x 26 = 2147483650字节
如果你仔细观察创建的文件,我很确定最后一行被截断,文件大小正好是2147483647,即2 ^ 31-1.
你不能写一个更大的文件的原因是由于文件系统的限制,但更可能是因为你编译了一个(非大文件识别)32位二进制文件,一个文件不能超过2147483647因为它是可以使用的最大有符号整数.
如果是这种情况,并且您的操作系统是64位,最简单的解决方法是设置正确的编译器标志以构建64位二进制文件,该二进制文件不具有此限制.
否则,请查看abasterfield解决方法.