DOUBLE, CURRENCY, VAL e CDBL

Sono reduce da un brutto periodo dove la salute venuta a mancare.
Sono rimasto fermo con il mio progetto del software di contabilit che ho ripreso da poco.

Un problema che ho riscontrato, uno di quei problemi serissimi l’arrotondamento finanziario…

Ho fatto molte prove su Mac OS, su Linux e su Windows e ho riscontrato serissimi errori nella funzione CDBL
in pratica numero.cdbl seppure numero una stringa es: ‘1236,270000000’ viene trasformata in un numero decimale a precisione doppia come il seguente 1236,2699999999982324.

e qui, va beh se ci penso bene se uso FORMAT ottengo comunque 1236,27 … ma quando i movimenti contabili diventano 1000 o 1500 e intendo sommare ad esempio il totale, mi ritrovo con uno scarto addirittura di 10, 20 centesimi.

con .VAL utilizzando il formato in precisione doppia con 4 decimali ( Currency ) sembra funzionare bene.

prendo ad esempio la funzione di arrotondamento che ho scritto …

Function arrotonda1(numero as variant, numerodecimali as integer) As Currency
dim numerodouble as Currency
dim numeroaltro as string
dim numerozero as string
dim risultatodbl as Currency
dim risultatostr as string
dim formatta as string
dim formattadecimale as string

numerodouble = 0.00
numeroaltro = “”
numerozero = “”
risultatodbl = 0.00
risultatostr = “”
formatta = “”
formattadecimale = “”

numerozero = “00000000000000”
// fino a 10 decimali

select case vartype(numero)
case 4,5,6

numerodouble = numero

case 8,18,19,20

if instr(0,numero,".") > 0 then 
  numero = replaceall(numero,".","")
end if

if instr(0,numero,",") > 0 then
  numero = replaceall(numero,",",".")
end if

numerodouble = val(numero)

case else
return 0

end select

formattadecimale = left(numerozero,numerodecimali)
if formattadecimale <> “” then
formatta = “###,###,###,###.” + formattadecimale
else
formatta = “###,###,###,###”
end if

if formattadecimale <> “” then
risultatostr = format(numerodouble,formatta) + “00000000000000”
else
risultatostr = format(numerodouble,formatta) + “.00000000000000”
end if

risultatodbl = risultatostr.Val
return risultatodbl
//// arrotonda nuovo metodo
End Function

E’ una funzione SCHIFOSA vero ?
Ma l’unica che non mi perde 10, 20 , 30 centesimi quando tento di stampare un bilancio proveniente da 4000 registrazioni contabili.

Detto questo, perche la funzione cdbl produce un numero con uno scarto, infinitesimale ma esiste ?

Potresti moltiplicare tutti i valori x 1.000.000.000

esempio 1236,270000000 x 1.000.000.000 = 1236270000000

in questo modo sommi tutti numeri interi,
alla fine fai totale / 1.000.000.000 e tutto dovrebbe tornare al centesimo

Buon lavoro

Il suggerimento di Enzo corretto.
Magari x 1 miliardo forse esagerato. Dovresti vedere il tuo valore di approssimazione massimo (centesimi, millesimi o altro) e moltiplicare di conseguenza, lavorando con gli interi.

In ogni caso il problema che in contabilit dovresti usare currency e non double.

ho risolto utilizzando campi di tipo currency e variabili currency al posto di double.
Ora non esistono scarti di centesimi

rs.field(“prova”).Currency invece di rs.field(“prova”).Doublevalue
row.CurrencyColumn(“prova”) invece di row.DoubleColumn(“prova”)

e una funzione di arrotondamento che usa variabili di tipo currency anzich di tipo double
ovviamente utilizzando val al posto di cdbl

Bene