Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 29
  1. #1

    [C] casting

    Ciao a tutti!
    Vi sottopongo il seguente esempio:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    double Xmax,Xmin,Xn,grid;
    int    nX;
    
    main()
    {
      Xmax = -20.100000;   
      printf("Xmax = %lf\n",Xmax);
      Xmin = -46.900000;
      printf("Xmin = %lf\n",Xmin);
      grid = 0.2;
      printf("grid = %lf\n",grid);
      Xn=(Xmax-Xmin)/grid;
      printf("Xn = %lf\n",Xn);
      nX=(int)Xn;
      printf("nX = %d\n",nX);
    
      return 0;
    }
    L'output e' il seguente:

    Xmax = -20.100000
    Xmin = -46.900000
    grid = 0.200000
    Xn = 134.000000
    nX = 133

    PERCHE'???

    Ovviamente io vorrei che, dopo aver eseguito il casting (int), nX sia un intero, con valore 134 ...

  2. #2
    A me da il risultato atteso nx=134 :master:

  3. #3

    Re: [C] casting

    Originariamente inviato da gulpgiulia
    Ciao a tutti!
    Vi sottopongo il seguente esempio:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    double Xmax,Xmin,Xn,grid;
    int    nX;
    
    main()
    {
      Xmax = -20.100000;   
      printf("Xmax = %lf\n",Xmax);
      Xmin = -46.900000;
      printf("Xmin = %lf\n",Xmin);
      grid = 0.2;
      printf("grid = %lf\n",grid);
      Xn=(Xmax-Xmin)/grid;
      printf("Xn = %lf\n",Xn);
      nX=(int)Xn;
      printf("nX = %d\n",nX);
    
      return 0;
    }
    L'output e' il seguente:

    Xmax = -20.100000
    Xmin = -46.900000
    grid = 0.200000
    Xn = 134.000000
    nX = 133

    PERCHE'???

    Ovviamente io vorrei che, dopo aver eseguito il casting (int), nX sia un intero, con valore 134 ...
    Anche a me da 133 !
    Ma se provi a cambiare la riga :
    nX=(int)Xn;
    in :
    nX=(int)(Xn+0.000001);
    Il risultato da float ad intero dipende da come il compilatore arrotonda il valore float.
    Questi floating point..., a volte fluttuano un pò troppo !
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  4. #4
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,565
    Basta dire al compilatore quante cifre dopo la virgola vuoi
    codice:
    cout <<ios::setprecision(2) << 3.5090921912
    darà 3.50
    "Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)

    "Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)

    http://xvincentx.netsons.org/programBlog

  5. #5
    Originariamente inviato da XWolverineX
    Basta dire al compilatore quante cifre dopo la virgola vuoi
    codice:
    cout <<ios::setprecision(2) << 3.5090921912
    darà 3.50
    Non è questione di visualizzazione, ma del risultato di operazioni con valori float.
    Che per ovvie ragioni devono essere in qualche modo arrotondate,
    e che quindi possono dare risultati 'imprecisi'.
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jul 2001
    Messaggi
    1,003

    Re: Re: [C] casting

    Originariamente inviato da Samuele_70
    Anche a me da 133 !
    Ma se provi a cambiare la riga :
    nX=(int)Xn;
    in :
    nX=(int)(Xn+0.000001);
    Il risultato da float ad intero dipende da come il compilatore arrotonda il valore float.
    Questi floating point..., a volte fluttuano un pò troppo !
    Mi sembra che qui succeda proprio l'incontrario.
    Cioè che la mantissa del float contenga un numero tipo 1.339999 (per 10^2) e che il printf riconosca l'evidente errore di approsimazione, mentre il casting se ne sbatte (ovviamente) e prende la parte intera (133)

  7. #7
    Innanzitutto grazie a tutti!
    Poi, come dice Samuele_70, non e' questione di visualizzazione. So bene che quello che succede e' necessario e inevitabile (non esiste nella realta' dei calcoli il continuo dei numeri reali), e anche in qualche modo "compilatore-depending". Ma il punto e': come affrontare nel modo piu' saggio/semplice/proficuo il problema? Mi spiego meglio: nell'esempio che vi ho proposto, i valori Xmax, Xmin sono costanti numeriche, cosi' come pure Xn e nX, ma in realta' Xmax e Xmin sono variabili, calcolate nel programma a partire da dati di input, e cosi' pure sono Xn e nX. Inoltre, nX e' utilizzato nel corso del programma, ed e' importante che abbia il valore "esatto". Quello che succede e' proprio quanto descritto da tia86: la mantissa del float contiene un numero tipo 1.339999 (per 10^2), il printf riconosce l'evidente errore di approsimazione (e scrive Xn = 134.000000), mentre il casting (ovviamente) prende la parte intera (133).
    Cosa conviene fare in questi casi/di solito come si procede? Scrivere una routine che, dato un numero reale, ne esegue l'approssimazione (e non l'operazione "parte intera"), cioe' es. 133.2 --> 133 ma 133.5 (e 133.9999)--> 134 ? Esistono soluzioni standard per questi casi, o solo "fai-da-te" (tipo struttura if e confronto)? Altro? Cosa fareste?
    Grazie!

  8. #8
    ... la storia si ripete!
    Nel mio programma c'e un certo parametro, y, a valori decimali (quindi definito come double). Io vorrei che il file di output del programma contenga nel nome l'informazione sul valore del parametro. Quindi trasformo l'informazione in un int e costruisco la stringa che contiene il nome del file di uscita. Esempio:
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    double y;
    int    infoy;
    char   OutputFile[80];
    main()
    {
      y=0.6;
      printf("y = %lf\n",y); 
      infoy=y*100;
      printf("infoy = %d\n",infoy); 
      sprintf(OutputFile,"OutputFiles_%d.dat",infoy);
      return 0;
    }
    Ecco l'output:
    y = 0.600000
    infoy = 59
    OutputFile_59.dat

    E' evidente che si tratta di qualcosa di completamente analogo a quanto esposto prima. Ma il problema rimane. Io mi aspetto che, se imposto y=0.6 come valore del parametro, si produca un file il cui nome e' OutputFile_60.dat. E invece questo file non esiste! E se lo vado a cercare con il nome che mi aspetto che abbia, ovviamente, non lo trovo! Vi siete mai imbattuti in problemi simili? Si tratta di una situazione tipica? Come viene risolta di norma? Cosa fareste?

  9. #9
    Puoi 'aggirare' il problema usando per il risultato della moltiplicazione
    una variabile float, che poi passerai con un cast a quella int, così tagli
    la parte decimale senza arrotondameti.
    codice:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
    	double y, tmp;
    	int    infoy;
    	char   OutputFile[80];
    	
    	y=0.6;
    	printf("    y = %f\n", y); 
    	tmp=y*100;
    	printf("  ris = %f\n", tmp);	
    	infoy=(int)tmp;
    	printf("infoy = %d\n", infoy); 
    	sprintf( OutputFile, "OutputFiles_%d.dat", infoy);
    	printf(" file = %s\n", OutputFile);
    	return 0;
    }
    01010011 01100001 01101101 01110101 01100101 01101100 01100101 01011111 00110111 00110000
    All errors are undocumented features waiting to be discovered.

  10. #10
    Ti ringrazio, ho provato con la variabile temporanea, e cosi' funziona. Ma cosa mi garantisce che funzioni sempre? Mi sembra che abbiamo spostato il problema al caso generale, ovvero il primo esempio che ho presentato. Anche li' Xn e' una variabile temporanea, su cui opero il casting per avere un valore intero.
    La mia domanda e': possibile che in C non sia presente una funzione/routine/algoritmo/qualsiasi cosa che impedisca il presentarsi di tali errori di troncamento e soprattutto renda il codice indipendente dal compilatore? (Come abbiamo detto prima, facendo riferimento al primo esempio, con lo stesso codice io otengo nX=133, king64 ottiene nx=134)
    Grazie
    Giulia

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.