2013-12-14 4 views
5

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 

ここでは何が起こっていますか?

ありがとうございます。

+0

を含める前に、あなたのコード内で

#define _FILE_OFFSET_BITS 64 

を入れては '2147483648LL'は本当に' 2147483648ULL'ではないでしょうか? (一方で、 '0'と '1'に 'LL 'を追加する必要はありません。) –

+2

その時点で、2G出力サイズに非常に近いはずです。 FSまたはulimitの制限? – Mat

+0

'fprintf'の結果を調べて、それが否定的でないことを確認してください。 –

答えて

6

各行は26文字の長さ、82595525行×26 = 2147483650バイト

作成したファイルに近い見てみると、私は最後の行は切り捨てられ、ファイルサイズが正確2147483647、つまりはかなり確信しています2^31-1。

大きなファイルを書き込めない理由は、ファイルシステムの制限に起因するものですが、(ファイルを認識していない)32ビットバイナリをコンパイルしている可能性があります。使用できる最大の符号付き整数であるため、2147483647以上である必要があります。

OSが64ビットの場合は、この制限がない64ビットバイナリを構築するための適切なコンパイラフラグを設定するのが最も簡単な解決方法です。

それ以外の場合は、abasterfieldの回避策をご覧ください。

+1

または#define _FILE_OFFSET_BITS 64 64ビットの前に2^31バイトを超えるファイルを使用することができましたプロセッサーが一緒に来た! – abasterfield

+0

@abasterfieldそれを指摘してくれてありがとう。 – jlliagre

+0

私は、この問題がファイルシステムに関連する可能性があるとは想像もできませんでした。あなたの説明のためにありがとう:) –

3

CFLAGS -D_FILE_OFFSET_BITS=64でコンパイルするか、いずれかのlibcのヘッダ

+0

ありがとう、あなたのソリューションは完全に働いた:) –

関連する問題