Strana cosa che avviene correggendo un sorgente C da Pc a Pc

di il
25 risposte

Strana cosa che avviene correggendo un sorgente C da Pc a Pc

Ciao a tutti.
Io sto facendo la tesi di laurea in economia, dove praticamente abbiamo creato un economia artificiale con il linguaggio C. Il programma come output genera dei file di testo (blocco note) con varie informazioni su questo finto sistema economico. Settando le costanti in modo adeguato io da questi file di testo riesco ad ottenere dei grafici con un certo andamento (questi infatti vengono poi dati "in pasto" al software R e si generano dei grafici).
Il problema è che nel mio computer i dati generati dal sorgente sono di un certo tipo, se il programma viene corso sul pc del mio relatore sono degli altri. Abbiamo anche provato a far correre lo stesso identico programma (è lo stesso file c che passo io a loro) al tecnico informatico della facoltà..e a lui vengono dei risultati (e quindi poi dei grafici) ancora diversi dai nostri...non si riesce a capire il perchè, visto che il codice è lo stesso. Voi avete esperienza in tal senso? Di codici che su macchine diverse producono risultati diversi? E da cosa potrebbe dipendere?
Abbiamo pensato che potesse dipendere da una libreria esterna che utilizziamo..e che genera numeri casuali, ma provando a creare un piccolo programma che genera numeri casuali sfruttando quella libreria..i numeri generati dal mio pc e da quello del mio relatore sono uguali..quindi non dovrebbe dipendere da quello.
Ogni vostra esperienza che ricorda questa situazione e ben accetta.
Vi passerei il sorgente ma è veramente lunghissimo...se qualcuno a voglia potrei passarglielo e così può farsi un'idea..
Grazie in anticipo.

25 Risposte

  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Viene corso ... correre ... è un linguaggio economico?

    Eseguire ... un programma viene eseguito ...

    Da quello che dici è impossibile dirti cosa succede ... non sappiamo neanche in "cosa" siano diversi i grafici in questione ...
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Rosas ha scritto:


    Il problema è che nel mio computer i dati generati dal sorgente sono di un certo tipo, se il programma viene corso sul pc del mio relatore sono degli altri.
    [...]
    Abbiamo pensato che potesse dipendere da una libreria esterna che utilizziamo..e che genera numeri casuali
    Ciao,
    spesso la generazione dei numeri casuali si basa su un valore detto seed. Se il seed è uguale allora il generatore di numeri casuali darà sempre gli stessi numeri, e questo ti permette di ripetere lo stesso esperimeno più volte. Se invece i seed sono diversi allora anche i numeri generati saranno diversi.
    Quello che si fa solitamente è
    srand(time(NULL));
    cioè si inizializza il generatore di numeri casuali con un seed che dipende da informazioni sull'orario (restituite dalla funzione time). Se voi utilizzate questo metodo allora per forza i numeri verranno sempre diversi. Se volete sempre le stesse sequenze di numeri allora dovete trovare il modo di fissare il seed.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    minomic ha scritto:


    Rosas ha scritto:


    Il problema è che nel mio computer i dati generati dal sorgente sono di un certo tipo, se il programma viene corso sul pc del mio relatore sono degli altri.
    [...]
    Abbiamo pensato che potesse dipendere da una libreria esterna che utilizziamo..e che genera numeri casuali
    Ciao,
    spesso la generazione dei numeri casuali si basa su un valore detto seed. Se il seed è uguale allora il generatore di numeri casuali darà sempre gli stessi numeri, e questo ti permette di ripetere lo stesso esperimeno più volte. Se invece i seed sono diversi allora anche i numeri generati saranno diversi.
    Quello che si fa solitamente è
    srand(time(NULL));
    cioè si inizializza il generatore di numeri casuali con un seed che dipende da informazioni sull'orario (restituite dalla funzione time). Se voi utilizzate questo metodo allora per forza i numeri verranno sempre diversi. Se volete sempre le stesse sequenze di numeri allora dovete trovare il modo di fissare il seed.
    Il seed per la generazione dei numeri casuali è lo stesso. Non utilizziamo la funzione srand e rand (con il time interno della macchina) per i numeri casuali ma una libreria esterna. Il suo codice è questo:
    #define IM1 2147483563
    #define IM2 2147483399
    #define AM (1.0/IM1)
    #define IMM1 (IM1-1)
    #define IA1 40014
    #define IA2 40692
    #define IQ1 53668
    #define IQ2 52774
    #define IR1 12211
    #define IR2 3791
    #define NTAB 32
    #define NDIV (1+IMM1/NTAB)
    #define EPS 1.2e-7
    #define RNMX (1.0-EPS)
    
    float ran2(long *idum)
    {
    	int j;
    	long k;
    	static long idum2=123456789;
    	static long iy=0;
    	static long iv[NTAB];
    	float temp;
    
    	if (*idum <= 0) {
    		if (-(*idum) < 1) *idum=1;
    		else *idum = -(*idum);
    		idum2=(*idum);
    		for (j=NTAB+7;j>=0;j--) {
    			k=(*idum)/IQ1;
    			*idum=IA1*(*idum-k*IQ1)-k*IR1;
    			if (*idum < 0) *idum += IM1;
    			if (j < NTAB) iv[j] = *idum;
    		}
    		iy=iv[0];
    	}
    	k=(*idum)/IQ1;
    	*idum=IA1*(*idum-k*IQ1)-k*IR1;
    	if (*idum < 0) *idum += IM1;
    	k=idum2/IQ2;
    	idum2=IA2*(idum2-k*IQ2)-k*IR2;
    	if (idum2 < 0) idum2 += IM2;
    	j=iy/NDIV;
    	iy=iv[j]-idum2;
    	iv[j] = *idum;
    	if (iy < 1) iy += IMM1;
    	if ((temp=AM*iy) > RNMX) return RNMX;
    	else return temp;
    }
    #undef IM1
    #undef IM2
    #undef AM
    #undef IMM1
    #undef IA1
    #undef IA2
    #undef IQ1
    #undef IQ2
    #undef IR1
    #undef IR2
    #undef NTAB
    #undef NDIV
    #undef EPS
    #undef RNMX
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Ok, facciamo un test... Prova ad eseguire questo codice:
    
    #define IM1 2147483563
    #define IM2 2147483399
    #define AM (1.0/IM1)
    #define IMM1 (IM1-1)
    #define IA1 40014
    #define IA2 40692
    #define IQ1 53668
    #define IQ2 52774
    #define IR1 12211
    #define IR2 3791
    #define NTAB 32
    #define NDIV (1+IMM1/NTAB)
    #define EPS 1.2e-7
    #define RNMX (1.0-EPS)
    
    #include <stdio.h>
    
    float ran2(long *idum)
    {
       int j;
       long k;
       static long idum2=123456789;
       static long iy=0;
       static long iv[NTAB];
       float temp;
    
       if (*idum <= 0) {
          if (-(*idum) < 1) *idum=1;
          else *idum = -(*idum);
          idum2=(*idum);
          for (j=NTAB+7;j>=0;j--) {
             k=(*idum)/IQ1;
             *idum=IA1*(*idum-k*IQ1)-k*IR1;
             if (*idum < 0) *idum += IM1;
             if (j < NTAB) iv[j] = *idum;
          }
          iy=iv[0];
       }
       k=(*idum)/IQ1;
       *idum=IA1*(*idum-k*IQ1)-k*IR1;
       if (*idum < 0) *idum += IM1;
       k=idum2/IQ2;
       idum2=IA2*(idum2-k*IQ2)-k*IR2;
       if (idum2 < 0) idum2 += IM2;
       j=iy/NDIV;
       iy=iv[j]-idum2;
       iv[j] = *idum;
       if (iy < 1) iy += IMM1;
       if ((temp=AM*iy) > RNMX) return RNMX;
       else return temp;
    }
    
    int main(int argc, char const *argv[])
    {
       int i=0;
       long idum = 54321;
       for(i=0; i<10; ++i) {
          printf("[%d]  %g\n", i, ran2(&idum));
       }
       return 0;
    }
    
    
    #undef IM1
    #undef IM2
    #undef AM
    #undef IMM1
    #undef IA1
    #undef IA2
    #undef IQ1
    #undef IQ2
    #undef IR1
    #undef IR2
    #undef NTAB
    #undef NDIV
    #undef EPS
    #undef RNMX
    
    L'output che ottengo è il seguente:
    
    [0]  0.655416
    [1]  0.200995
    [2]  0.893622
    [3]  0.281887
    [4]  0.525
    [5]  0.314127
    [6]  0.444616
    [7]  0.299474
    [8]  0.610057
    [9]  0.591368
    
    Ottieni gli stessi numeri?

    EDIT - Anche cambiando il valore che ho dato alla variabile idum ottengo sempre gli stessi 10 valori... Forse c'è qualcosa che non ho capito?
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    minomic ha scritto:


    Ok, facciamo un test... Prova ad eseguire questo codice:
    
    #define IM1 2147483563
    #define IM2 2147483399
    #define AM (1.0/IM1)
    #define IMM1 (IM1-1)
    #define IA1 40014
    #define IA2 40692
    #define IQ1 53668
    #define IQ2 52774
    #define IR1 12211
    #define IR2 3791
    #define NTAB 32
    #define NDIV (1+IMM1/NTAB)
    #define EPS 1.2e-7
    #define RNMX (1.0-EPS)
    
    #include <stdio.h>
    
    float ran2(long *idum)
    {
       int j;
       long k;
       static long idum2=123456789;
       static long iy=0;
       static long iv[NTAB];
       float temp;
    
       if (*idum <= 0) {
          if (-(*idum) < 1) *idum=1;
          else *idum = -(*idum);
          idum2=(*idum);
          for (j=NTAB+7;j>=0;j--) {
             k=(*idum)/IQ1;
             *idum=IA1*(*idum-k*IQ1)-k*IR1;
             if (*idum < 0) *idum += IM1;
             if (j < NTAB) iv[j] = *idum;
          }
          iy=iv[0];
       }
       k=(*idum)/IQ1;
       *idum=IA1*(*idum-k*IQ1)-k*IR1;
       if (*idum < 0) *idum += IM1;
       k=idum2/IQ2;
       idum2=IA2*(idum2-k*IQ2)-k*IR2;
       if (idum2 < 0) idum2 += IM2;
       j=iy/NDIV;
       iy=iv[j]-idum2;
       iv[j] = *idum;
       if (iy < 1) iy += IMM1;
       if ((temp=AM*iy) > RNMX) return RNMX;
       else return temp;
    }
    
    int main(int argc, char const *argv[])
    {
       int i=0;
       long idum = 54321;
       for(i=0; i<10; ++i) {
          printf("[%d]  %g\n", i, ran2(&idum));
       }
       return 0;
    }
    
    
    #undef IM1
    #undef IM2
    #undef AM
    #undef IMM1
    #undef IA1
    #undef IA2
    #undef IQ1
    #undef IQ2
    #undef IR1
    #undef IR2
    #undef NTAB
    #undef NDIV
    #undef EPS
    #undef RNMX
    
    L'output che ottengo è il seguente:
    
    [0]  0.655416
    [1]  0.200995
    [2]  0.893622
    [3]  0.281887
    [4]  0.525
    [5]  0.314127
    [6]  0.444616
    [7]  0.299474
    [8]  0.610057
    [9]  0.591368
    
    Ottieni gli stessi numeri?

    EDIT - Anche cambiando il valore che ho dato alla variabile idum ottengo sempre gli stessi 10 valori... Forse c'è qualcosa che non ho capito?
    Si, mi vengono gli stessi tuoi risultati.
    Comunque quel codice lì non viene eseguito direttamente. Viene incluso con #include <ran2.h> e poi nel codice viene richiamato ogni volta che serve la generazione di un numero casuale. Viene posto appena iniziato il main, idum = -7345287;
    E se ad esempio si vuole generare un numero tra 0 e 20 si fa: ran2(&idum)*20.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Ok, allora secondo me la parte di generazione dei numeri casuali funziona correttamente. Evidentemente c'è un'altra spiegazione.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    minomic ha scritto:


    Ok, allora secondo me la parte di generazione dei numeri casuali funziona correttamente. Evidentemente c'è un'altra spiegazione.
    Infatti. Ma allora cos'è che fa generare dei dati dentro i file di output diversi da macchina a macchina se non è la componente casuale? A parte quello sono istruzioni oggettive.
    Se vuoi ti mando il file di tutto il programma (l'esecuzione dura 2-3 minuti) e si generano una quarantina di file blocco note. Tu potresti guardare nel file df_production e farmi vedere quanto ti vengono i valori di quella stramaledetta produzione così li confronto coi miei.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Dai, proviamo che sono curioso.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Io sono uscito di casaxd...ti mando il sorgente appena torno...spero di ritrovarti..se non stasera domani!
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Scusate se mi intrometto nella discussione, ma è curioso e sono interessato.

    Non mi è chiara una cosa e ho un dubbio:
    Comunque quel codice lì non viene eseguito direttamente. Viene incluso con #include <ran2.h> e poi nel codice viene richiamato ogni volta che serve la generazione di un numero casuale. Viene posto appena iniziato il main, idum = -7345287;
    E se ad esempio si vuole generare un numero tra 0 e 20 si fa: ran2(&idum)*20
    proviamo a fare un test con questo idum nel main, che risultato abbiamo?

    io questo:
    [0] 17.8316
    [1] 2.7523
    [2] 19.1334
    [3] 1.53529
    [4] 7.12946
    [5] 10.6337
    [6] 15.8921
    [7] 19.8833
    [8] 1.36074
    [9] 13.1083
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Ho provato e ottengo gli stessi identici numeri di SVNiko.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Mimomic tu lavori su una macchina a 64bit giusto?

    Il mio timore è che su qualche macchina va in overflow e quindi ha il problema di generare numeri diversi. Se ti va possiamo provare con idum diversi in modo da provare a mandare le macchine in overflow.
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    SVNiko ha scritto:


    Mimomic tu lavori su una macchina a 64bit giusto?

    Il mio timore è che su qualche macchina va in overflow e quindi ha il problema di generare numeri diversi. Se ti va possiamo provare con idum diversi in modo da provare a mandare le macchine in overflow.
    In effetti ci avevo pensato anche io, ma non credo che il problema sia questo perché sto lavorando su una macchina a 32 bit. Adesso provo ad eseguire lo stesso codice su una Windows 64 bit.

    EDIT - Confermo che ottengo gli stessi numeri anche sotto Windows 64 bit. Il mistero resta...
  • Re: Strana cosa che avviene correggendo un sorgente C da Pc a Pc

    Il problema dell'overflow non può essere?

    Io lo sto testando su una macchina linux64

    Io resto perplesso e ritengo possa essere anche un problema di overflow.

    Se questo codice ci fornisce risultati uguali allora il problema risiede nel codice che non conosciamo.
Devi accedere o registrarti per scrivere nel forum
25 risposte