Newsgroup: it.comp.lang.visual-basic
Titolo: Funzione Round: Qualcuno sa illuminarmi?

Ciao a tutti !
Avendo bisogno di arrotondare a due decimali un valore numerico, ho scelto
di usare la Round(), e per caso ho scoperto una cosa molto singolare:
Provando a fare Round(23.465, 2) mi dà 23.46, mentre Round(33.465, 2) mi
dà 33.47. Me la spiegate ???
E' un errore dovuto a una determinata versione di VB (io ho la 6.0SP5) o
altro (ho Win2kPRO come S.O.) ?
Penso anche che se il problema è diffuso (come temo che sia), potrebbero
esserci imprecisioni di questo genere in numerosi programmi VB che
"manipolano" dati numerici provenienti da DB o altro (o sono solo io che
ho pensato erroneamente di usare la Round per arrotondare ?).
Comunque ho risolto creandomi una mia funzione Round (che ci tocca fare
per aggirare Bill...):
'------------------------------------------------------------
'Function   myRound
'
'Esegue l'arrtondamento "a mano". Per arrotondare
'porta il numero al decimale che si vuole arrotondare, per
'esempio se si vuole arrotondare a 2 decimali si aggiunge
' 0.005 se si vuole arrotondare a 3 0.0005 e così via
'poi si tronca al numero di decimali desiderato
'------------------------------------------------------------
Function myRound(dToRound As Double, iNrDec As Integer) As Double
 
 Dim lsNrConvertito As String
 
 lsNrConvertito = CStr(5 / (10 ^ (iNrDec + 1)) + dToRound)
 lsNrConvertito = Replace(lsNrConvertito, ",", ".")
 myRound = Val(Mid(lsNrConvertito, 1, InStrRev(lsNrConvertito, ".") +
iNrDec))
 
End Function
Ciao !!!
*Roby*
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 ha scritto nel messaggio
news:bkc4k5$26r$1...@news.newsland.it...

se usi la format (es format(33.465, "0.00") ) questo problema non c'è

 se usi la format (es format(33.465, "0.00") ) questo problema non c'è
Hai ragione, ci ho pensato e anche a me funziona, ma mi è stato affermato
che su alcune macchine (dove il programma gira e non c'è VB, o meglio c'è
solo la runtime) la format tronca il valore, quindi otterrei 33,46...
Comunque il mio messaggio era anche una considerazione su una funzione VB
bacata che può trarre in inganno molti programmatori (penso al suo
possibile uso in applicativi di contabilità ma non solo).
Grazie comunque per il suggerimento.
Ciao,


 solo).
Non è un baco.
E' un comportamento normale in considerazione del tipo di dati che utilizzi.
La sfortuna di VB è che, consentendo un uso 'allegro' della tipizzazione,
non richiede di considerare aspetti che in altri linguaggi diventano
critici, per cui ci si incazza non appena una cosa è 'non intuitiva'.
In programmi di contabilità, ad esempio, nessuno usa i double per gli
importi, come faresti tu,
proprio perchè la loro rappresentazione (perchè di rappresentazione si
tratta) decimale non è necessariamente concorde con la memorizzazione, per
cui la tua osservazione non pone problemi.
ciao
Alberto

 mi dà 33.47. Me la spiegate ???
No, ma, se la cosa, invece di spingerti al suicidio, può consolarti, la
guida ufficiale di VB (Indice, "CInt, funzione"), dice, fra l'altro:
"Se la parte frazionaria è esattamente uguale a 0,5, le funzioni CInt e CLng
la arrotonderanno al numero pari più prossimo."
Ed è pure vero, basta provare con 2.5 o 3.5
Ora, fermo restando che ho un tot di ferite e, forse per questo, anche il
dente avvelenato, sarò proprio scemo io quando dico che bevono, in altri
termini, più "professionali e civili", chi è quel cretino, figliendrocchia,
sniffatore-dopo-che-ha-scoperto-il-fegato-fottuto-dall'alcool che ha deciso
che i numeri interi pari sono parecchio diversi da quelli dispari?
Se ci riesco io (per chi, sul SC, vuol spulciare all'interno dei progetti,
c'è una certa ARROTONDA), noto e riconosciuto
[be|cogli|fetent|bastard|pratic|[etc_in_libertà]]one, perchè quell'immenso
pirla non ha finito il suo lavoro?
Ok, forse arriveranno un tot di post sul trattamento computerizzato dei
numeri decimali, rispondo prima e subito: se anche fosse (io ho sempre i
miei certibubbi [TM°]), non c'azzecca un tubaccio.
Ad Albe (di cui ho appena letto il post prima di spedire) dico che lo fa
anche con valori dichiarati Currency che, per quel che ne so e fra i numeri
decimali, è il tipo più "affidabile"...

 sempre i miei certibubbi [TM°]), non c'azzecca un tubaccio.
The behavior of this method follows IEEE Standard 754, section 4. This kind
of rounding is sometimes called rounding to nearest, or banker's rounding.
non è sempre colpa loro, qualche volta si adeguano agli standard degli
altri.
--
Salutoni
Sergio

[*CSSoft*=
news...@cssoft2001.com
] ha scritto:

Bene, allora, in piena, cosciente, personale e totale responsabilità,
affermo che si beve anche nel comitato IEEE!
Ma, cazzarola, in che universo mi trovo?

 affermo che si beve anche nel comitato IEEE!
Puede ser.
Sono ingegneri.
Alberto

 Sono ingegneri.
Categoria che riesce a farsi "riconoscere" anche a livello internazionale...
;-)
ciao
ugo

[*Albe V°*=
vaccariTO...@hotmail.com
] ha scritto:

E magari (perdona, ma me l'hai offerta su un piatto d'argento) ... "dei
migliori" ;-)

 Sono ingegneri.
quindi, nel caso, tavernello? ;-)
--
Salutoni
Sergio

 typed:

ROTFL :D

[*CSSoft*=
news...@cssoft2001.com
] ha scritto:

Naaa, per quanto quella culetta-leccatina (ora non mi viene il nome) mi
rovini la digestione, meglio decisamente un tuo (vicino) Franciacorta.

 Franciacorta.
Sě, ma mi stavo riferendo a quanto, da altre parti, si dice sulle abitudini
bevitorie del nostro ing.
A meno che le sue scorte siano destinate solo agli ospiti, e in qualche
gavone siano nascosti altri nettari. :-)
--
Salutoni
Sergio

 Ma, cazzarola, in che universo mi trovo?
Tu hai tutte le ragioni del mondo.
Ciò non toglie che L'IEEE si è trovato di fornte ad un problema impossibile:
ovvero rappresentare numeri decimali a virgola mobile in nostazione binaria
esponenziale senza perdere precisione.
Ai tempi feci questa funzione:
Function binrap(n As Double) As String
Dim n1 As Double
n1 = Int(n)
If n1 >= 1 Then
    While n1 >= 1
        If Int(n1 / 2) * 2 <> n1 Then
            binrap = "1" & binrap
            n1 = (n1 - 1) / 2
        Else
            binrap = "0" & binrap
            n1 = n1 / 2
        End If
    Wend
Else
    binrap = "0"
End If
n = n - Int(n)
n1 = 1 / 2
If n <> 0 Then
    binrap = binrap & "."
    While n <> 0
        If n - n1 > 0 Then
            binrap = binrap & "1"
            n = n - n1
        ElseIf n - n1 < 0 Then
            binrap = binrap & "0"
        Else
            binrap = binrap & "1"
            n = 0
            Exit Function
        End If
        n1 = n1 / 2
    Wend
End If
End Function
Serve a visualizzare la rappresentazione binaria lineare di un valore
double.
Più o meno corrisponde alla mantissa all'interno della rappresentazione
binaria esponenziale (quella del comitato IEEE, per intenderci)
Se provi a chiamare tale funzione con argomenti apparentemente innocui, per
esempio  binrap("23,465"), ti accorgi che il numero di bit necessari per
rappresentare *esattamente* tale numero è superiore a quello gestibile con
un double (epr la precisione è infinito).
Perciò si applicano approssimazioni, piccole in questo caso, ma sufficienti
a portare il valore un poco sotto o un poco sopra a 23,465. La round fa il
resto.
Fermo restando che nella parte decimale 33.465 e 43.465 sono identiche anche
in notazione binaria e quindi il round dovrebbe comportarsi alla stessa
maniera, cosa che non avviene.
x:termoPilucco


Veramente lo bevo perfino a casa, oltre ad ascoltare chi tu sai (in macchina
da solo, ovviamente).
Alberto
-- 
Rigore č quando arbitro fischia

 macchina da solo, ovviamente).
epperchè se c'hai qualcuno in parte ti strangola :-)
--
Salutoni
Sergio

 Tu hai tutte le ragioni del mondo.
In questo caso, sě, decisamente e presuntosamente, sě!
Cancello tutto il tuo resto, peraltro validissimo, ma la domanda resta
sempre quella (riguardo CLng e CInt):
Qual č la differenza fra un pari e un dispari (escludendo un quinto, rosso o
bianco che sia, di piů o di meno)?

 epperchè se c'hai qualcuno in parte ti strangola :-)
Non posso escluderlo.
Alberto

 Dalla vendemmia in poi, però, le strade si dividono.
scusa l'imprecisione riguardo al "tradizionale" ;-) , è che davo per
scontato che, se uno si fa una cosa in casa, lo faccia seguendo appunto una
"tradizione". è anche vero che c'è gente che si fa il sidro partendo dai
tetrapack di succo di mela, ma non stiamo qui a sottilizzare troppo.
comunque, più che alla somiglianza vino-aceto, pensavo più al fatto che chi
si dà la pena di fare le cose buone ha di solito le papille abbastanza
raffinate, e davanti al tavernello, una papilla raffinata, di solito, si
rifiuta.
ma il mondo, lo sappiamo, è bello perchè è avariato ;-)
il pudore mi ha costretto a taggare il post...
--
Salutoni
Sergio

 Non posso escluderlo.
Ora, a parte che le mie conoscenze sulla qualità della birra sono pari al
mistero dell'ALEF (copyright by Cantor, che però sto leggendo, sperando di
capirci), la curiosità è grande: Chi cacchio ascolta Albe in macchina?

 Ma, cazzarola, in che universo mi trovo?
In realtà il tutto ha una sua logica.
Tempo fa avevo chiesto al gruppo di matematica se è più corretto usare 
la convenzione che vede arrotondato il .5 per eccesso, per difetto o nel 
modo "bancario".
Beh, la risposta è che è appunto una convenzione.
Statisticamente è più corretto il sistema bancario, quindi quello VB, 
perchè il .5 si trova esattamente a metà tra due numeri, quindi 
arrotondando sempre per eccesso si avrebbe una distorsione dei valori 
verso l'alto.
Quindi facendo uno in su e uno in giù statisticamente i valori sono 
corretti.
Ciao

 corretti.
Bene, sarebbe come dire che, quando t'incontro (ovviamente spersonalizzando
il tutto), una volta ti meno e l'altra no...
La statistica è una scienza (per me non è nemmeno "scienza", è solo
un'invenzione delle TV, dei politicanti e dei (anch'essi) giocherelloni
monopolisti per agire prima e tranquillamente negare poi) inesatta, per
_scientifica_ definizione.

 un'invenzione delle TV
La statistica è quella cosa per cui se non credi alla statistica, 
statisticamente fai parte di quelli che non ci credono.
Sono d'accordo.
Infatti la mia logica è che un evento o si verifica o non si verifica.
Ciao