Ich habe viele verschiedene Pseudozufallszahlengeneratoren in C geschrieben, die eine beliebige Anzahl von Paaren von Zufallszahlen generieren (über die CLI) und speichern sie in einem (neue) Textdatei: ein Paar Zahlen pro Spalte. Ich möchte 400.000.000
Zahlen in einer Textdatei speichern, aber wenn ich mir die Anzahl der Zeilen der Datei anschaue, hat sie nur 82.595.525 Zeilen. Dies ist der Code:Ich kann nur eine endliche Anzahl von Zeilen in einer neuen Textdatei speichern
#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;
}
Zuerst ich, dass es im Verdacht, wo einige Problem im Code (dh ich die falschen Arten von Variablen irgendwo entschieden werden könnte), aber ich es getestet, indem in der for-Schleife ein, einschließlich if (i > 165191050) printf ("%llu\n", i);
(daran erinnern, dass ich ein 1-D-Array für die Speicherung von Paaren von Zahlen, nicht ein 2D-verwenden, so in der Bedingung multipliziere ich einfach 82595525*2
), um zu testen, ob das Problem war, dass der Code nicht 800.000.000
mal looping war, aber nur 165191050
. Als ich den Test nach i = 165191050
durchführte, fing es gerade an, i
Werte auf der Schale auszudrucken, so dass es diese 800.000.000
Mal wirklich schlingerte, aber als ich die Anzahl der Zeilen der erzeugten Textdatei sah, gab es wieder 82595525
Zeilen. Also ich wette, das Problem ist nicht im Code (oder zumindest nicht in den Arten von Variablen, die ich verwendet habe).
ich auch die gleichen Ergebnisse mit diesem Algorithmus erhalten (dies ist nur eine andere unterschiedliche Pseudozufallszahlengenerator):
#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;
}
Wieder Schleifen es 800.000.000
mal, aber es speichert nur 165191050
Zahlen.
$ ./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
Was geht hier vor?
Vielen Dank im Voraus.
Sollte nicht '2147483648LL' wirklich' 2147483648ULL' sein? (Es ist nicht notwendig, 'LL' zu' 0' und '1' auf der anderen Seite hinzuzufügen.) –
Sie sollten an diesem Punkt sehr nahe der 2G-Ausgabegröße sein. FS oder ulimit Einschränkungen? – Mat
Überprüfen Sie das Ergebnis von 'fprintf' und vergewissern Sie sich, dass es nicht negativ ist. –