Newsgroup: it.comp.lang.delphi
Titolo: Resto...

Ciao  tutti,
            ho un problema di matematica ......
In sostanza devo fare tre somme .... in teoria dovrebbero dare lo stesso 
risultato, ma in pratica ho delle diversita'.
Ecco il problema:
Devo fare una chiusura mensile che, ovviamente, tiene conto di tutti gli 
incassi giornalieri e questa somma da un certo valore e la metto a video 
(per esempio 10+15+20....+37=500).
Una volta avuto la somma totale la divido per i giorni lavorativi e ho la 
media giornaliera (500 / 24)
Ora questo 10 e' suddiviso in 4 diversi sottoincassi il cui totale da 10.
2 + 1.2  + 5.5 + 1.3 = 10 (e cosi' anche per gli altri)
Anche in questo caso sommo i quattro valori e li metto a video in 4 colonne 
diverse, come il caso precedente prendo il ogni valore finale e lo divido 
per i giorni lavorativi (sempre 24 dell'esempio precedente).
Il bello e' che se sommo le medie giornaliere non ho il 500 finale ma ho una 
discrepanza che a volte raggiunge anche una unita'.
Per arrotondare uso TRUNC(X) ma credo che i decimali che lascio indietro 
alla fine generano il difetto.
Come posso ovviare a cio' ???
Grazie
Daniele 

Che formato usi per i floating-point?
double, real, single, extedend? lavorano con esponente e mantissa e possono
dare degli errori di approssimazione
prova ad usare i currency. anche loro soffrono sull'approssimazione ma molto
meno.
L'help di delphi potra fugare ogni tuo dubbio in merito.
bye,
Raktzo

 (per esempio 10+15+20....+37=500).
*Mai* usare un formato a virgola mobile per memorizzare degli importi di 
denaro.  E' un errore comune e gravissimo.  Bisogna sempre utilizzare 
degli interi.  In Delphi esiste il tipo Currency proprio per ovviare. 
Viene riportato tra i "real types" ma è in realtà un intero a 64 bit 
opportunamente scalato perché abbia 4 cifre decimali.

 decimali.
Anche solo 4 decimali sono troppi ..... dovrei evidenziarne 2 (visto che con 
la nostra moneta ce ne sono due ..), vale sempre il trunc per i due decimali 
?? o il round ??
Scusami per la banalita' delle domande, ma non ho mai usato il Currency dato 
che non avevo mai avuto l'occasione di incontrare problematiche simili.
Domani provo.
Grazie, Daniele
PS : Per la cronaca .... in mancanza di meglio (idee !!) avevo utilizzato 
l'extended, GLOM ! 

 ?? o il round ??
Né l'uno, né l'altro.  I 4 decimali del Currency costituiscono la 
precisione massima.  Se devi visualizzare il valore, usa la funzione 
FormatCurr (versione thread-safe).
Tra parentesi, comunque, tieni presente che anche se la nostra valuta 
prevede normalmente 2 cifre dopo la virgola, esistono contesti in cui è 
richiesta una precisione superiore (ad esempio di 5 decimali) e per i 
quali neanche il Currency basterebbe.  In quei casi è sempre bene usare 
interi a 64 bit e gestire in modo analogo al Currency le cifre decimali.

Ciao,
       Ho fatto un po di prove ..... ma ho sempre dei risultati diversi.
Come da suggerimento ho usato la variabile Currency .... e tanto per la 
cronaca metto il corpo del reato !!!
          Totale             Articolo1      Articolo2     Articolo3
A)       8000                6700            919.56         380.44
B)       2666.67           2233.33       306.52         126.81        ( Ho 
diviso A per 3 [ A / 3] )
C)     69333.33          58066.67     7969.52       3297.15       ( Ho 
moltiplicato B per 26 [B * 26] )
Come vedi la somma della riga A di Articolo1+2+3 da 8000 (ma sara' un caso 
!!!)
Mentre la somma della riga B non da 2666.67 e lo stesso vale per la C.
Quello che devo ottenere e' che la somma dei vari articoli dia come 
risultato il valore di Totale.
Ricapitolando, si prende il valore del totale della giornata, lo si somma ai 
valori precedenti (diviso per i vari articoli) e si ha il toatale e li 
divide per i giorni di lavoro cosi' da avere la media giornaliera (B).
La media poi la si moltiplica per i giorni lavorativi e si ha la proiezione 
a fine mese con quella media (C).
I decimali in questo caso possono andare e venire ..... ma l'effetto visivo 
potrebbe dare fastidio.
Se riesci a darmi una mano .....
Grazie, Ciao
Daniele 

        Ho fatto un po di prove ..... ma ho sempre dei risultati diversi.
Certo, è normale.  Quando lavori con i formati a virgola mobile (fosse 
anche Currency) non puoi ignorare le regole dell'approssimazione dovute 
al fatto che stai usando un formato a rappresentazione finita (le cifre 
decimali massime sono sempre in numero finito e questo vale anche nel 
calcolo manuale).  Dividere 1000 per 3 significa ottenere un numero 
periodico che non puoi, necessariamente, rappresentare precisamente: 
0.67 è la necessaria approssimazione di 0.66666666......  Nel tuo caso 
poi, c'è una propagazione dell'errore perché sommi quantità già 
approssimate: la divisione di una somma propaga un errore minore che la 
somma delle divisioni.  In sostanza, devi rassegnarti al fatto che i 
risultati vengono fuori necessariamente approssimati e non puoi farci 
nulla.  Tentativi di migliorare la precisione possono essere l'uso di 
una libreria ad aritmetica con precisione multipla oppure eseguire i 
calcoli conservando le frazioni originali.

Ciao, grazie per la risposta ...
Stavo pensando ad un modo per tenere in memoria tutti i decimali in modo da 
non avere troppi problemi !
Comunque se ci sono questi problemi ...... come fanno le case di software a 
fare i programmi di gestione bilancio ????
Anche loro avranno questi problemi no ??
Spero di leggerti in giornata..... domani inizia una trasferta e non so come 
leggerti.
A proposito, com'e' possibile leggere queasto news da un internet poin ??
Ciao e grazie ancora
Daniele 

 A proposito, com'e' possibile leggere queasto news da un internet poin ??
Via web: 
http://www.newsland.it/