Newsgroup: it.lavoro.informatica
Titolo: perchè devo buttare via il mio tempo per stupidi errori dei programmi?

>>>>  
http://www.bb2002.it
 :)  <<<<<
........... [ al lavoro ] ...........

 da dove pnmmb salta fuori quel centesimo di zreqn?
 
precisione dei floating-point?
 
situazione analoga: programma che calcola il prezzo da pagare, 14.40 euro, 
lo passa all'app dei pagamenti che lo vuole in centesimi (quindi moltiplicato
per 100) e il pagamento viene 14.39.

 da dove pnmmb salta fuori quel centesimo di zreqn?
 
Non usare float ma decimanli a cifre fisse, in alternativa usa interi moltiplicati e divisi per un moltiplicatore almeno del doppio dell'ordine di grandezza della precisione decimale che ti interessa
 
Problema vecchissimo per chi fa gestionali.
 
Ciao
  Francesco

 Non usare float ma decimanli a cifre fisse
 
eh, purtroppo il gestionale non mi permette di selezionare queste cose: o 
numero o testo e pedalare, solo la stampa permette di impostare un formato 
(nr decimali)
 
e perdipiù ti dico anche che i valori numerici sono salvati in un file DBF 
come testo... roba del 1998 e anche prima, spero che lo cambino in tempi 
brevi


 da dove pnmmb salta fuori quel centesimo di zreqn?
 
Il fatto che tu scriva software e lo stia chiedendo, e` preoccupante.
 
https://spin.atomicobject.com/2014/08/14/currency-rounding-errors/
 
 
 


Se, per decisioni sbagliate di altri, un programmatore si trova a dover 
gestire campi floating per calcoli valutari, esistono sistemi 
standardizzati per arrivare ad un risultato corretto? Mi verrebbe in 
mente di usare campi di appoggio con un numero di decimali definito e 
riversare il dato "addomesticato" di nuovo nel campo floating, che mi 
sembra, piu' o meno, cio' che suggerisce l'estensore dell'articolo.
 
-- 
The three most dangerous things in the world are a programmer with a 
soldering iron, a hardware type with a program patch and a user with an 
idea.

 standardizzati per arrivare ad un risultato corretto?
 
diciamo che dal punto di vista matematico l'errore è quasi sempre 
trascurabile essendo su svariati decimali dopo la precisione che 
si utilizza nei calcoli finanziari. quindi non è nella correttezza 
del risultato il problema.
 
il problema si manifesta quando si va a rappresentare il numero "impreciso":
se io ho 1.99999999998 e lo rappresento (ad esempio in fattura) con 
2 decimali ottengo un bel 1.99 anziché 2.00 atteso.
 
il workaround minimo in questi casi è usare funzioni di arrotondamento prima
di rappresentare il numero. quello ottimale sarebbe arrotondare dopo ogni
operazione.


Quindi agire direttamente sul campo float ?...oppure ho capito male?


 Quindi agire direttamente sul campo float ?...oppure ho capito male?
 
direi che hai capito bene.
considera che sono le operazioni aritmetiche che introducono l'errore,
nel momento in cui le fai seguire dal giusto arrotondamento lo correggi.
considera anche che stiamo parlando di un workaround per intervenire sul
codice preesistente laddove non è ragionevolmente possibile togliere i
float.

 
 
il fatto che tu abbia postato senza leggere i miei DUE post (11 righe in 
tutto) è altresì preoccupante, altrimenti non avresti nemmeno fatto il 
saccente dicendomi cose che so benissimo


 
 
dettaglio il motivo della lamentela:
 
all'inizio, a fronte di un importo di 20784.60 dovevo calcolare uno sconto 
del 2.5%, corrispondente a 519.615
 
In stampa, impostata la maschera con due decimali, il software mi mette 
519.62, arrotonda da solo (verso l'alto)
 
L'importo scontato, 20264.985, viene quindi stampato come 20264.99 (altro 
arrotondamento verso l'alto)
 
E la banca ci fa notare che x.60 - y.62 fa z.98 e non z.99
 
 
a questo punto intervengo e modifico la formula dello sconto, 
moltiplicandolo per -1 e per 100 (-51961.5), troncando i decimali (INT: 
-51961) e ridividendolo per 100 (-519.61)
adesso lo sconto è -519.61 e il totale in fondo è corretto: 20264.99
 
però nel caso descritto nell'OP:
totale prima dello sconto : 16.688
calcola il 2.5% di sconto : 417,2   (giusto giusto, senza arrotondamenti)
moltiplica lo sconto per -1 e poi 100 : 41.721   :O
 
dato che in una moltiplicazione cambiando l'ordine dei fattori il prodotto 
non cambia, ho "risolto" invertendo le ultime due: prima rimoltiplico per 
100, poi faccio il negativo
 
e qui il software ci azzecca e mette il valore giusto :)
 
mah...


 e qui il software ci azzecca e mette il valore giusto :)
 
fai bene a virgolettare il "risolto". cambiando la sequenza delle operazioni
hai semplicemente cambiato il numero su cui si manifesta il problema.

 il fatto che tu abbia postato senza leggere i miei DUE post
 
Nah. Non ci provare. Mi basta leggere il tuo post originale per sapere che certe cose non le sai benissimo. Anzi, non le sai affatto.

 standardizzati per arrivare ad un risultato corretto?
 
No. 
 

 operazione.
 
Ma che dici. Il problema degli errori di round-off e` la loro propagazione nei calcoli. Arrotondare dopo ogni operazione significa amplificare il problema, propagando un errore ancora piu` ampio. Non esiste ALCUN workaround all'utilizzo di un tipo intrinsecamente impreciso per la rappresentazione di valori che devono essere precisi.  
 

 a questo punto intervengo e modifico la formula dello sconto, 
 
Bravo. Bella stronzata. Hai semplicemente fatto in modo che l'errore venga fuori su altri numeri. Ripeto, il fatto che tu scriva software e risolva a questo modo i problemi e` preoccupante.

 amplificare il problema, propagando un errore ancora piu` ampio. 
 
assolutamente no. visto che l'errore è sulla n-esima cifra significativa 
e visto che l'arrotondamento non lo fai su quella cifra, è matematico che 
in questo modo l'errore lo elidi.
semmai è al contrario, se l'errore te lo porti dietro con le operazioni 
successive c'è il caso che venga amplificato. 
 

 impreciso per la rappresentazione di valori che devono essere precisi.
 
in realtà non è vero neanche questo. la precisione che garantisce un 
double (52 bit significativi) è ben superiore a quella normalmente 
richiesta per i calcoli finanziari. infatti non è la precisione il 
problema in questione.
 

 
 
bene: alla luce di quanto scritto, del calcolo che devo fare e degli 
strumenti che ho a disposizione, come lo risolveresti?
 
originale : INT( 16688 * 2.5% * 100) * (-1) / 100
modificata: INT( 16688 * 2.5% * 100) / 100 * (-1) 
 
database DBF del 1998, campo numerico senza possibilità di impostare la 
precisione o il tipo
 
s.o. da win XP in su



Quoto, sebbene in taluni ambiti, dove ad esempio viene richiesto l'uso 
di 6 decimali, la precisione di un double possa rivelarsi insufficiente.
Mi ricordo che ai tempi della vecchia lira turca, quando per 1 euro ci 
volevano circa 2.000.000 di lire turche, fare delle conversioni di 
grossi importi, con 6 cifre decimali, un double si troncava 
regolarmente! Sebbene dal punto di vista del valore le differenze erano 
quisquilie, dal punto di vista contabile erano squadrature.
 

 
 
e comunque stiamo parlando di UNA-DUE cifre decimali, mica di quelle 
dell'errore del Pentium, che iniziavano alla QUARTA nel peggiore dei casi e 
che si verificavano in uno su 9 miliardi di casi


 
 
ma avete mai provato BAMBOCCI ad usare il COBOL per scrivere gestionali?
 
un bel gestionale si fa in COBOL.....ghe ne minga de ball!
 
-- 
Quando la dittatura è un dato di fatto, la rivoluzione diventa un diritto.
(Victor Hugo)


Ed errore di progettazione
Da quando si usano i floating point per calcoli gestionali ?
E' da sin dai tempi del COBOL che i calcoli vengono fatti con i fixed 
decimal,all'inizio il COBOL non aveva i floating point.
 

 
 
Una stupidata
Come se non fosse possibile avere i fixed decimal in altri linguaggi.
In C++ ho la mia libreria per gestire i fixed decimal,va fino a 2**31 
cifre per una cpu a 32 bit
Esistono librerie persino per il C.

 Da quando si usano i floating point per calcoli gestionali ?
 
 
è arrivato lo strolago di brozzi che riconosce i pruni al tatto e la merda 
al puzzo.
ho postato l'esempio di una cosa sbagliata, lui scopre che è sbagliata.
 


Nel tuo thread del post non c'e una risposta del genere
Non mi sono messo a leggere tutti i thread del post
 


non importava scorrersi tutto il thread ma bastava le poche righe che hai 
quotato. lo scrivo subito che si tratta di un round-off error legato ai 
floating point.
 
fermo restando che si trattava di un programma cordova, quindi 
javascript, che non ha nativamente una alternativa. 
 
conoscere il problema in primis permette la soluzione più corretta, che 
non è prendere una posizione oltranzista. non tutti sanno che il round-
off error non è prerogativa dei floating point binari: anche la "umana" 
rappresentazione decimale soffre di questo problema, come la mettiamo 
quando devi rappresentare in decimale 1/3?


Lo puoi rappresentare esattamente solo come frazione
E ritornando al discorso non importa se il problema era dovuto ai fp o no.
La mia risposta era solo una precisazione ad una tua affermazione
Niente polemiche quindi
 

 
<<da dove pnmmb salta fuori quel centesimo di zreqn?
 
 
 
il colmo sono le fatture di alcuni centri commerciali ( tipo leroy merlin mi 
pare l'ultima che ho visto) , con molte righe su una pagina:
 
il totale delle righe esposte è 100 , il totale a fondo pagina è 101,3
 
(dovuto al fatto che nelle righe  prima somma e poi arrotonda , invece nel 
fondo pagina prima arrotonda e poi somma ) !!!!