Cで書かれたさまざまな擬似乱数ジェネレータを使用して、任意の数の乱数を生成し(CLIを介して)、それらを(新しい)テキストファイル:1列あたりの数字のペア。私は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ループA内を含むことによってそれをテストしたところ、私はそれが疑わ:これはコードですif (i > 165191050) printf ("%llu\n", i);
(2次元のものではなく、1組の数値を格納するために1次元配列を使用していることを思い出して、条件にちょうど82595525*2
を掛けて)問題がコードがループしていないかどうかをテストします800.000.000
回、ただ165191050
です。私がテストを行ったときに、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
数字を格納します。
$ ./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
ここでは何が起こっていますか?
ありがとうございます。
を含める前に、あなたのコード内で
を入れては '2147483648LL'は本当に' 2147483648ULL'ではないでしょうか? (一方で、 '0'と '1'に 'LL 'を追加する必要はありません。) –
その時点で、2G出力サイズに非常に近いはずです。 FSまたはulimitの制限? – Mat
'fprintf'の結果を調べて、それが否定的でないことを確認してください。 –