[C] Precisione macchina float e double

di phanorat il
23 risposte
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

  • 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
  • Sono ancora al buio. : / non capisco cosa centrino le promotion ne le costanti. Dammi qualche altro indizio pls
  • Togli tutti i 2.0 e 1.0 e scrivi semplicemente 2 e 1

    P.S. E' inutile che visualizzi 64 cifre ...
  • Fatto! Ma continuano a darmi sempre il medesimo output..
  • Ovvero ? Quale codice hai scritto ?
  • #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;   
    }
    
  • Hai ricompilato?

    Il risultato è

    0.0000001192092895507812500000000000000000000000000000000000000000
    0.0000000000000002220446049250313100000000000000000000000000000000
  • Si, hi ricompilato.. ma mi da sempre lo stesso.. Non so.. può dipendere dal compilatore o dall'architettura?
  • 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
  • Ma double non va stampato con %lf e float con %f???
    Prova un po
  • 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
  • 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?
  • Si ho provato anche quello ma non funziona
  • 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