[C] Precisione macchina float e double

di il
23 risposte

[C] Precisione macchina float e double

Salve a tutti, dovrei creare, per una materia universitaria, un programma che calcoli la precisione macchina in singola e doppia precisione. Ho gia scritto il codice, il problema è che le due funzioni una float, l'altra double, mi restituiscono il medesimo risultato. Il sizeof sui tipi mi ritorna 8byte per i double e 4 per i float.



#include <stdio.h>
#include <stdlib.h>

float precisioneSingola(){
 float eps = 1.0;
 while((1.0 + eps) > 1.0)
  eps = eps / 2.0;
 return(2 * eps);      
}

double precisioneDoppia(){
 double eps = 1.0;
 while((1.0 + eps) > 1.0)
  eps = eps / 2.0;
 return(2 * eps);      
}

int main(){
 printf("%.64f\r\n",precisioneSingola());
 printf("%.64f\r\n",precisioneDoppia());
 printf("%d %d",sizeof(double),sizeof(float));
 system("PAUSE");
 return 0;   
}

23 Risposte

  • Re: [C] Precisione macchina float e double

    L'errore e' banale ed anche subdolo: devi ristudiare come funzionano le regole di promozione dei tipi numerici e, soprattutto, come si scrive una costante!

    E con questo ti si dovrebbe illuminare, non una lampadina, ma un intero albero di natale
  • Re: [C] Precisione macchina float e double

    Sono ancora al buio. : / non capisco cosa centrino le promotion ne le costanti. Dammi qualche altro indizio pls
  • Re: [C] Precisione macchina float e double

    Togli tutti i 2.0 e 1.0 e scrivi semplicemente 2 e 1

    P.S. E' inutile che visualizzi 64 cifre ...
  • Re: [C] Precisione macchina float e double

    Fatto! Ma continuano a darmi sempre il medesimo output..
  • Re: [C] Precisione macchina float e double

    Ovvero ? Quale codice hai scritto ?
  • Re: [C] Precisione macchina float e double

    #include <stdio.h>
    #include <stdlib.h>
    
    float precisioneSingola(){
     float eps = 1;
     while((1 + eps) > 1)
      eps = eps / 2;
     return(2 * eps);      
    }
    
    double precisioneDoppia(){
     double eps = 1;
     while((1 + eps) > 1)
      eps = eps / 2;
     return(2 * eps);      
    }
    
    int main(){
     printf("%.64f\r\n",precisioneSingola());
     printf("%.64f\r\n",precisioneDoppia());
     printf("%d %d",sizeof(double),sizeof(float));
     system("PAUSE");
     return 0;   
    }
    
  • Re: [C] Precisione macchina float e double

    Hai ricompilato?

    Il risultato è

    0.0000001192092895507812500000000000000000000000000000000000000000
    0.0000000000000002220446049250313100000000000000000000000000000000
  • Re: [C] Precisione macchina float e double

    Si, hi ricompilato.. ma mi da sempre lo stesso.. Non so.. può dipendere dal compilatore o dall'architettura?
  • Re: [C] Precisione macchina float e double

    Va bene, non ci siete ancora!

    1) le costanti vanno scritte come 1.0f e 2.0f per assicurarsi che siano float

    2) le regole di promozione dei tipi dicono che l'espressione numerica viene valutata nel tipo numerico piu' esteso, ma prima di essere valutata, vengono convertiti tutti gli operandi:

    short -> int -> long -> float -> double
  • Re: [C] Precisione macchina float e double

    Ma double non va stampato con %lf e float con %f???
    Prova un po
  • Re: [C] Precisione macchina float e double

    Ho provato anche a stamparlo con lf ma non cambia nulla. Poi a oregon funziona.. Deve essere qualcosa che non riguarda il codice forse l'architettura. @migliorabile Non capisco ancora cosa centrino le costanti e la promozione.. posta la soluzione se ce l'hai
  • Re: [C] Precisione macchina float e double

    phanorat ha scritto:


    posta la soluzione se ce l'hai
    Mi sembra che ti abbia detto di provare con 1.0f e 2.0f ... non l'hai letto?
  • Re: [C] Precisione macchina float e double

    Si ho provato anche quello ma non funziona
  • Re: [C] Precisione macchina float e double

    phanorat ha scritto:


    Si ho provato anche quello ma non funziona
    Mooooolto strano:

    usando le costanti in versione 1.0, nell'implementazione di precisioneDoppia
    e 1.0f nell'implementazione di precisioneSingola, funziona perfettamente:
    
    0.0000001192092895507812500000000000000000000000000000000000000000
    0.0000000000000002220446049250313080847263336181640625000000000000
    8 4
    
    Funziona anche solo scrivendo le costanti come valori interi, come ti era gia' stato detto da @oregon, sempre per la storia della promozione dei valori numerici:
    
    0.0000001192092895507812500000000000000000000000000000000000000000
    0.0000000000000002220446049250313080847263336181640625000000000000
    8 4
    
    Invece NON FUNZIONA se nell'implementazione della funzione precisioneSingola scrivi le costanti come 1.0 e 2.0, sempre per colpa della storia sulla promozione dei valori numerici
    
    0.0000000000000002220446049250313080847263336181640625000000000000
    0.0000000000000002220446049250313080847263336181640625000000000000
    8 4
    
    Quindi il problema non e' nel codice, se scritto in modo corretto, ma da qualche altra parte!

    1) non hai scritto le costanti nel modo corretto
    2) hai una versione del compilatore che non gestisce i float in modo corretto
    3) boh!
Devi accedere o registrarti per scrivere nel forum
23 risposte