Newsgroup: it.comp.lang.c
Titolo: Errore di calcolo con variabili double 2!

Ciao a tutti.
Innanzi tutto vorrei ringraziare Andrea per la cortese risposta.
Come mi avevi chiesto riscrivo parte del programma. (In realtà non è
realizzato in c puro, ma è un mix di c e c++ per questo non lo avevo postato
prima).
Posto una funzione intera altrimenti....si potrebbe capire poco.
/***************************************************************************
***********************************************
Altra domanda......per la serie ......visto che vi ho già rotto le
scatoline....ne approfitto! :-P
Premetto che questa domanda è un pò OT......
Qualcuno conosce compilatori PURI di C e di C++?
Per puro di C intendo che il compilatore "non accetti" istruzioni tipiche
c++. Ad  es. for(int i=0; i<100;i++) o altro del genere.
Per puro di C++ intendo un compilatore standardizzato ANSI/ISO! Cioè che,
per intenderci, non accetti l'inclusine degli header in questo modo:
     #include <iostream.h>
bensì in quest'altro
      using namespace.........
****************************************************************************
**********************************************/
void Name(int Parameter)
{
 //creo e inizializzo le variabili locali
//Newname e Oldname sono variabili globali
 double ControlVariable,CalculateVariable;
 int CastingVariable=0;
 ControlVariable=CalculateVariable=Parameter;
 int Number=0;
 int i=0,k=0;
 for(i=0;i<1800;i++)//Newname è definito come: "char Newname[1800];"
   {
    Newname[i]='\0';
   }
 //trasferisco nella var Oldname il contenuto della var ffblk.ff_name
 for(i=0;i<13;i++)//Oldname è definito come: "char Oldname[13];"
   {
    Oldname[i]=ffblk.ff_name[i];
   }
 for(;CalculateVariable>=1;)
    {
     CalculateVariable=CalculateVariable/10;
     ControlVariable=ControlVariable/10;
    }//alla fine del ciclo in calculatevar. e in controlvar. c'è 0,....
 CalculateVariable=CalculateVariable*10; //ora ottengo k,....
ControlVariable=ControlVariable*10;
 for(int Counter=1; Counter= =1;Number++)//Il ciclo è potenzialmente
infinito....ma viene terminato da un controllo all'interno del ciclo stesso.
    {
     CastingVariable=int(CalculateVariable);//trasferisco il valore da una
variabile nell'altra
     switch(CastingVariable) //CastingV. è intera perchè solo così posso
fare lo "switch"
    {
     case 0:
      Newname[Number]='0';
      break;
     case 1:
      Newname[Number]='1';
      break;
     case 2:
      Newname[Number]='2';
      break;
     case 3:
      Newname[Number]='3';
      break;
     case 4:
      Newname[Number]='4';
      break;
     case 5:
      Newname[Number]='5';
      break;
     case 6:
      Newname[Number]='6';
      break;
     case 7:
      Newname[Number]='7';
      break;
     case 8:
      Newname[Number]='8';
      break;
     case 9:
      Newname[Number]='9';
      break;
     default:
      printf("Errore di sistema! Carattere non riconosciuto!!\n\r");
      printf("Premere un qualsiasi tasto per terminare...");
      getch();
      exit(1);
      break;
    }
     if(ControlVariable= =Parameter)
       {
        Counter=0;//mi fa uscire dal ciclo
       }
/* Queste 3 righe sono il mio tentativo fallito per evitare di avere errori
di calcolo.....le scrivo ma non servono a nulla. Sicuramente ho sbagliato
qualcosa.
     CalculateVariable=CalculateVariable;//Con questa riga cercavo di
reinserire il valore..della serie se è una approssimazione magari così il
valore diventa.."giusto"
     CalculateVariable=CalculateVariable/9;//Queste 2 righe sono la prova
del 9....eseguita in malomodo.....
     CalculateVariable=CalculateVariable*9;
*/
// QUI SOTTO HO L'ERRORE! Dopo aver eseguito il ciclo passando come
parametro a questa funzione il valore 1001. Il programma "sbaglia" il
calcolo.
    CalculateVariable=CalculateVariable-double(CastingVariable);
//Da qui in poi il valore è sbagliato e tutto il resto viene
conseguentemente sbagliato.
     CalculateVariable=CalculateVariable*10;
     ControlVariable=ControlVariable*10;
    }
 //controllo dove "finisce" Newname
//Questa parte della funzione l'ho fatta tanto per avere un risultato, ma
non è ottimizzata. Cioè ho scoperto che k è uguale a Number....però lo devo
ancora
//controllare!
 for(i=0;i<1800;i++)
   {
    if(Newname[i]!='\0')
      {
       continue;
      }
    else
      {
       k=i;//salvo in k il valore di i
       i=1900;//esce dal ciclo
      }
   }
  //e riempio la parte successiva con l'estensione ad es. ".jpg" Newname
conterrà alla fine il nome di un file!
  Newname[k]='.';
  Newname[k+1]='j';
  Newname[k+2]='p';
  Newname[k+3]='g';
}
Mi pare ci sia tutto.....ah no...ringrazio anticipatamente chi volesse
rispondermi!
Ciao
Al
P.S. Mi fareste sempre una grande cortesia a mandarmi una mail
qui....grazie.......
nealg...@tiscali.it

       using namespace.........
Di compilatori solo C o solo C++, soprattutto e' praticamente impossibile 
che un compilatore C++ non sia in grado di compilare in C (se no salterebbe 
per es la possibilita' di includere codice C in un sorgente C++).
Il GCC (e tutti i suoi porting per le varie piattaforme, qualunque sia il 
loro nome) lo fa' certamente, l'importante e' che tu specifichi 
l'estensione corretta per i sorgenti (si basa su quello per decidere) 
oppure lo forzi a farlo specificando le opportune opzioni. Leggi la man 
page del GCC per avere i dettagli.
Credo pero' che tutti i compilatori facciano un lavoro di analisi 
dell'estensione dei file per decidere se compilare in C o in C++.
-- 
Mox
"Trust the programmer."
"Don't prevent the programmer from doing what needs to be done."
"Keep the language small and simple."
"Provide only one way to do an operation."

 Posto una funzione intera altrimenti....si potrebbe capire poco.
Anche cosi' non e' che si capisca molto :-)
Come ti aveva paventato Griffini, giocare con valori reali su un
calcolatore
non e' una cosa salutare.
Nel punto da te indicato, dopo la sottrazione, il risultato e'
0.00099999999999989
e non
0.001
come ti saresti aspettato.
Tutto l'ambaradan che hai messo in piedi, serve per trasformare in stringa
un valore intero. Si risolve tutto con
memset(Newname, 0, sizeof(Newname));
sprintf(Newname, "%d", Parameter);
strcat(Newname, ".jpg");
C:\>iao Angelo
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 che un compilatore C++ non sia in grado di compilare in C
Mox... Da te questa non me la sarei mai aspettata :-)
dumb.cpp
int main(void)
{
   char dumbStr[10] = "Mox, Mox. Questa non la dovevi dire";
   return 0;
}
error C2117: 'Mox, Mox. Questa non la dovevi dire' : array bounds overflow


strcat(Newname, ".jpg");
Oppure ancora piu' semplicemente con
   sprintf(Newname,"%i.jpg",Parameter);
(supponendo che quello che si vuole e' semplicemente
una stringa C contenente il nome del file)
Andrea

 Mox... Da te questa non me la sarei mai aspettata :-)
Uhmm, Angelo, visto che tu l'hai capita questa frase me la spieghi? Io non 
ce l'ho fatta a tradurla :)
Questa frase in effetti non ci doveva finire nel post, e' il risultato di 
varie riscritture e di vari cut&paste (sia di parole che di concetti :P).
Giuro che normalmente non scrivo cosi' male.


 ce l'ho fatta a tradurla :)
A dire il vero, subito dopo aver premuto il tasto di invio mi e' sorto
il dubbio di aver detto una str... stupidaggine :-)
Ma ormai il danno era fatto.
Io l'ho intesa come "Un compilatore C++ compila sempre il codice C",
e quello voleva essere un esempio del fatto che questo non e' sempre
vero: la forma fa schifo anche in C, ma e' legale (o almeno mi risulta
che lo sia).
Questo e' il perche' di quella risposta.
Spero di averti chiarito il tuo pensiero :-)


    sprintf(Newname,"%i.jpg",Parameter);
Si, ma come l'ho scritto io e' piu' comprensibile, si spezzano le
operazioni da fare di sicuro c'e' un calo prestazionale ma bisogna
considerare che non e' una operazione critica per quanto riguarda
l'impegno delle risorse e bla, bla, bla ...
La realta' e' che non mi e' passato neanche per l'anticamera del
cervello che si risolvesse tutto con una sola riga. :-)
