我有许多不同的伪随机数生成器,用C编写生成任意数量的随机数对(通过CLI)并将它们存储在(新)文本文件中:每列一对数字。我想在文本文件中存储400.000.000
个数字,但是当我查看文件所包含的行数时,它只有82.595.525行。这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#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
)来测试问题是代码是否没有循环{{1} }次,但只有800.000.000
。当我在165191050
之后执行测试时,它刚刚开始在shell上打印出i = 165191050
值,所以它确实循环了那些i
次,但是当我看到行的数量时生成的文本文件,再次有800.000.000
行。所以我打赌问题不在代码中(或者至少不在我使用的变量类型中)。
我也用这个算法得到了相同的结果(这只是另一个不同的伪随机数发生器):
82595525
同样,它循环#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#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
这里发生了什么?
提前致谢。
答案 0 :(得分:6)
每行长26个字符,82595525行x 26 = 2147483650字节
如果你仔细观察创建的文件,我很确定最后一行被截断,文件大小正好是2147483647,即2 ^ 31-1。
你不能写一个更大的文件的原因是由于文件系统的限制,但更可能的原因是你编译了一个(非大文件识别)32位二进制文件,文件不能用于超过2147483647,因为它是可以使用的最大有符号整数。
如果是这种情况,并且您的操作系统是64位,最简单的解决方法是设置正确的编译器标志以构建64位二进制文件,该二进制文件不具有此限制。
否则,请查看abasterfield解决方法。
答案 1 :(得分:3)
使用CFLAGS -D_FILE_OFFSET_BITS=64
或
#define _FILE_OFFSET_BITS 64
在包含任何libc标头之前,在代码中