2013-12-14 5 views
5

मैं सी में लिखे कई अलग अलग छद्म यादृच्छिक संख्या जनरेटर है कि यादृच्छिक संख्या के जोड़े की एक मनमाना संख्या (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; 
} 

पहले तो मुझे लगता है कि वहाँ संदिग्ध जहां कोड में कुछ मुद्दे (यानी मैं चर के गलत प्रकार कहीं चुनने जा सकता है), लेकिन मैं इसके लिए लूप एक अंदर सहित द्वारा परीक्षण: इस कोड है if (i > 165191050) printf ("%llu\n", i); (याद दिलाना है कि मैं संख्या के जोड़ों के भंडारण के लिए एक 1-डी सरणी का उपयोग कर रहा है, न कि 2-डी एक, हालत में तो मैं बस गुणा 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

नहीं '2147483648LL' वास्तव में' 2147483648ULL' होना चाहिए शामिल हैं? (दूसरी तरफ 'एलएल'' 0' और '1' जोड़ने की कोई आवश्यकता नहीं है।) –

+2

आपको उस बिंदु पर 2 जी आउटपुट आकार के बहुत करीब होना चाहिए। एफएस या उलटी सीमाएं? – Mat

+0

'fprintf' के परिणाम की जांच करें और सुनिश्चित करें कि यह नकारात्मक नहीं है। –

उत्तर

6

प्रत्येक पंक्ति है 26 वर्ण लंबा, 82,595,525 लाइनों x 26 = २१४७४८३६५० बाइट्स

यदि आप बनाई गई फ़ाइल के करीब लग रही है, मैं कर रहा हूँ काफी यकीन है कि अंतिम पंक्ति छोटा कर दिया है और फ़ाइल आकार ठीक 2147483647 है, यानी 2^31-1।

कारण आप एक बड़ी फ़ाइल नहीं लिख सकते हैं या तो फ़ाइल सिस्टम सीमा के कारण है, लेकिन इस तथ्य के कारण आप एक (गैर बड़ी फ़ाइल जागरूक) 32 बिट बाइनरी संकलित करते हैं, जिसके साथ कोई फ़ाइल नहीं कर सकती 2147483647 से अधिक हो क्योंकि यह सबसे बड़ा हस्ताक्षरित पूर्णांक है जिसका उपयोग किया जा सकता है।

अगर ऐसा है और अपने ओएस 64 बिट है अगर, सरल ठीक एक 64 बिट द्विआधारी जो इस सीमा के लिए नहीं होगा निर्माण करने के लिए उचित संकलक झंडे स्थापित करने के लिए है।

अन्यथा, वैकल्पिक हल abasterfield को एक नजर है।

+1

या #define _FILE_OFFSET_BITS 64 लोग 64 बिट से पहले 2^31 बाइट से अधिक फ़ाइलों का उपयोग करने में सक्षम थे प्रोसेसर के साथ आया था! – abasterfield

+0

@abasterfield वास्तव में, यह इंगित करने के लिए धन्यवाद। – jlliagre

+0

मैं कल्पना नहीं कर सका कि यह समस्या फाइल सिस्टम से संबंधित हो सकती है ... हर रोज हम कुछ नया सीखते हैं। आपके स्पष्टीकरण के लिए धन्यवाद :) –

3
CFLAGS -D_FILE_OFFSET_BITS=64 साथ

संकलित करने या अपने कोड में

#define _FILE_OFFSET_BITS 64 

डाल इससे पहले कि आप किसी भी libc हेडर

+0

बहुत बहुत धन्यवाद, आपका समाधान पूरी तरह से काम करता है :) –

संबंधित मुद्दे