Ho molti diversi generatori di numeri pseudo casuali scritti in C che generano un numero arbitrario di coppie di numeri casuali (tramite la CLI) e li memorizzano in un (nuovo) file di testo: una coppia di numeri per colonna. Voglio memorizzare i numeri 400.000.000
in un file di testo, ma quando guardo il numero di linee del file, ha solo 82.595.525 linee. Questo è il codice:Posso memorizzare solo un numero finito di righe in un nuovo file di testo
#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;
}
In un primo momento ho ritenuto sospetto che là dove qualche problema nel codice (ad esempio potrei essere scegliendo il tipo sbagliato di variabili da qualche parte), ma ho provato includendo all'interno del ciclo for un if (i > 165191050) printf ("%llu\n", i);
(ricorda che sto usando un array 1-D per memorizzare coppie di numeri, non uno 2-D, quindi nella condizione mi limito a moltiplicare lo 82595525*2
) per verificare se il problema era che il codice non era in loop 800.000.000
volte, ma solo 165191050
. Quando ho eseguito il test, dopo i = 165191050
, ho appena iniziato a stampare i valori i
sulla shell, quindi è stato effettivamente eseguito il ciclo di quelle 800.000.000
volte, ma quando ho cercato il numero di righe del file di testo generato, c'erano nuovamente le righe 82595525
. Quindi sto scommettendo che il problema non è nel codice (o almeno non nei tipi di variabili che ho usato).
Sto anche ottenere gli stessi risultati con questo algoritmo (questo è solo un altro diverso generatore di numeri pseudo-casuali):
#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;
}
Ancora una volta, loop 800.000.000
volte, ma solo negozi 165191050
numeri.
$ ./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
Cosa sta succedendo qui?
Grazie in anticipo.
Non dovrebbe '2147483648LL' davvero essere' 2147483648ULL'? (Non c'è bisogno di aggiungere 'LL' a' 0' e '1', d'altra parte.) –
Dovresti essere molto vicino alla dimensione dell'uscita 2G in quel punto. Limiti di FS o ulimit? – Mat
Controlla il risultato di 'fprintf' e assicurati che non sia negativo. –