Newsgroup: it.comp.appl.access
Titolo: BUG di calcolo di Access '97: come risolvete?

Veniamo al sodo: ho un campo QTA (Single) e un campo PREZZO UNITARIO
(Valuta).
1087,156  *   14,2854  =  15.530,4583224  che arrotondato al secondo
decimale da un Prezzo Totale di  15.530,46
Purtroppo Access da come risultato del calcolo: 15.530,454918457 che
arrotondato è 15.530,45
Nell'esempio ho presentato valori con parecchi decimali (è il caso di una
ferramenta), ma vi assicuro che il problema si pone anche con un numero di
decimali "normale".
L'errore d'approssimazione si verifica se uno dei campi è un Single/Double,
mentre se sono tutti valuta non ci sono problemi.
Ho risolto usando una funzione VBA alla quale do preventivamente in pasto la
QTA; la funzione è:
Function Pulisci(Valore As Variant) As Double
  Dim Dec As Byte
  Dec = Len(Valore) - InStr(Valore, ",")
  Valore = Valore + (0.5 / 10 ^ Dec)
  If InStr(Valore, ",") <> 0 Then
      If Len(Valore) - InStr(Valore, ",") > Dec Then
            Valore = Mid(Valore, 1, InStr(Valore, ",") + Dec)
      End If
  End If
  Pulisci = Valore
End Function
Quindi se il campo calcolato diventa: [totale]=pulisci(QTA)*[PREZZO
UNITARIO] i conti tornano.
Ma è una soluzione molto rozza che mi fa schifo: sicuramene c'è di meglio!
Quindi mi chiedo, come risolvete voi questa situazione?
Ciao a tutti, Oscar

 ha scritto nel messaggio
news:vvy37.4599$Pv.1...@news.infostrada.it...

Vai sul Sito Comune, Sezione General: la FAQ di Karl Danaubauer "Arrotondare
un numero alla cifra specificata (uso commerciale)" dovrebbe risolvere il
tuo problema.
--
Roberto
---------------------------------------------
il Sito Comune di it.comp.appl.access:
http://www.sitocomune.com
---------------------------------------------

 tuo problema.
Scusa Roberto, ma a parer mio la FAQ di Karl Donaubaur si limita a
effettuare arrotondamenti alla cifra decimale desiderata.
Questo non č un problema (tra l'altro la funzioncina sul Sito Comune č un
grande classico :-) ... il problema č che Access sbaglia proprio a fare i
calcoli con valori single!
Se provi a smacchinare con l'esempio che ho fatto nel post precedente non
crederai ai tuoi occhi.
Ora, la funzione che ho creato "riconduce" sulla retta via il valore single
del campo QTA, ma stento a credere che non ci siano vie piů semplici (magari
una funzione di Access).
E' inutile una routine che arrotondi correttamente il risultato sbagliato di
una moltiplicazione.
Il problema č: perchč sbaglia a fare queste moltiplicazioni?
E' un buco macroscopico considerando le milioni di copie di Access al mondo
... eppure non credo di avere le traveggole :-)
Ciao, Oscar

 arrotondato è 15.530,45
CUT
Dipende dal fatto che il tipo single non ha una elevata precisione e,
soprattutto, non e' affine (come tipo) al tipo valuta. Questo vuol dire che
quando fai la moltiplicazione access deve fare prima una conversione in un
formato comune, con conseguente perdita di informazioni, e poi moltiplicare
due valori gia' approssimati a causa del loro formato.
Cambia il tipo da sigle a double, risolverai il problema senza impegnare
piu' di tanto in termini di spazio. L'unico inconveniente che potresti avere
sara' quello di andare a segare i decimali in piu' che ti compariranno a
causa della conversione (e questo ti fara' capire l'origine
dell'inconveniente).
Ciao
Sib

 Ciao, Oscar
Scusami, ma non avevo ben conpreso che il tuo problema fosse il risultato
della moltiplicazione.
Ho "smacchinato"; sul mio PC, con il campo QTA di tipo Numerico con
lunghezza a Precisione singola ed il campo PREZZO UNITARIO di tipo Valuta,
ottengo come risultato della moltiplicazione 15530,
4584061035
; il prodotto
risulta diverso dal tuo (forse perché io l'ho digitato e magari invece tu lo
ottieni da un calcolo) ma ancora non esatto.
Se invece cambio la lunghezza di QTA in Precisione doppia, ottengo come
valore del prodotto 15530,4583224 , che è il valore esatto.
Questo è spiegabile dal fatto che, la rappresentazione interna binaria di
certi numeri in base 10, se la lunghezza del campo non è adeguata, potrebbe
avere una precisione non soddisfaciente, provocando un errore che viene
amplificato dalla moltiplicazione: nel qual caso basta usare una lunghezza
di campo maggiore, e nel tuo esempio ottieni addirittura un risultato
esatto.
Quindi, a mio modesto parere,  non mi sembra si possa parlare di bug, visto
che Access ti dà la possibilità di scegliere tra l'ottimizzazione della
memoria e l'esattezza dei calcoli.
Comunque, quando il risultato finale sono quattrini, non mi sembra sbagliato
impostare il tipo campo di ambedue i fattori a Valuta (naturalmente usando
un formato ad hoc per QTA); se non vado errato Access, in questo caso,
applicherebbe automaticamente per il prodotto un arrotondamento di tipo
commerciale.


 esatto.
Ringrazio te e Sib per la cortesia e la precisione della risposta.
Purtroppo avendo parecchie copie del DB in circolazione non posso cambiare
il tipo di dati del campo e usufruirò di quella funzione artigianale che ho
costruito a naso (e sa Dio come, sistema tutto).
Quello che non mi torna è che sulla carta, Cdbl(QTA)*Prezzo dovrebbe mettere
le cose a posto e invece il risultato continua a non essere corretto.
Ciao , Oscar


    Se QTA e Prezzo sono variabili di tipo diverso, durante la
moltiplicazione puoi avere dei brutti scherzi (dovuti alle necessarie
conversioni di tipo eseguite dietro le quinte). Cmq per calcoli di tipo
valutario è bene utilizzare il tipo Currency. Questo assicura la
rappresentazione decimale _esatta_ dei numeri frazionari fino alla 5a cifra
decimale ed, inoltre, assicura una distribuzione statistica uniforme degli
errori di arrotondamento introdotti.
    Ciao.

 errori di arrotondamento introdotti.
Sě, ho capito.
Ma resta il fatto che ci sono decine di .mdb in circolazione in cui viene
usato il tipo di dati single non certo per bellezza.
E che cavolo, il tipo di campo piů naturale in cui memorizzare numeri
piccoli o percentuali č senza dubbio il single (non sapendo a cosa si va
incontro).
Probabilmente risolveranno come ho fatto io.
Ciao, Oscar

incontro).
Concordo con te.
Il tipo di dati single pur essendo meno "capiente" del double dovrebbe comportarsi decentemente nei
calcoli, diversamente perchè l'hanno introdotto??
Comunque prova a usare questa funzione di normalizzazione del Single:
Function NormSingle(valore As Double) As Double
  Dim Dec As Byte
  Dec = Len(valore) - InStr(valore, ",")
  NormSingle = Fix("" & valore * (10 ^ Dec) + Sgn(valore) * 0.5) / (10 ^ Dec)
End Function
E' più semplice e performante della tua e fa la stessa cosa.
Il fatto stesso che la funzioncina rimetta le cose a posto fa intuire la scarsa logica con cui la
jet engine tratta i single nei calcoli.
Ciao, warp