Newsgroup: it.comp.lang.visual-basic
Titolo: 30,7 - 30 = 0,6999999999 xche????

Semplice problema:
volendo estrapolare la parte decimale di un numero ho scritto una funzione
che
che include la seguente operazione:
ParteDec = Abs(Fix(NumeroDaConvertire) - NumeroDaConvertire)
Il problema è che se p.e. NumeroDaConvertire=30.7  il risultato non è 0.7 ma
0.699999999.
Perche'?
E' un buco di VB (io ho vb6 con sp3 e w98).
Lo stesso errore lo da se inputo lo stesso calcolo (ma indicando
direttamente i numeri) nella finestra
del controllo immediato (ctrl+G).
Qualcuno sa rispondermi.
Grazie e caio
 _____________________
| Anicito Giuseppe
| 
an...@unosistemi.it

 Qualcuno sa rispondermi.
Arrotonda il risultato e tutto andrà bene.
La vera risposta alla tua domanda è che "Bill beve come una spugna!"

 La vera risposta alla tua domanda è che "Bill beve come una spugna!"
Già fatto, la vera risposta che mi aspettavo e' la seconda.
Ora inoltrero' la domanda alla MS. Vediamo che rispondono.
Ciao e grazie

 La vera risposta alla tua domanda è che "Bill beve come una spugna!"
Per una volta no ;-)
La vera risposta e' "Calcoli in virgola mobile"
Prova questo codice:
Dim a As Single, b As Double, c As Currency
a = 30.7
b = 30.7
c = 30.7
Debug.Print Abs(Fix(a) - a)
Debug.Print Abs(Fix(b) - b)
Debug.Print Abs(Fix(c) - c)
Ciao
--
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 ha scritto nel messaggio
news:a8sc8m$26s5$1...@phobos.ibnetwork.net...

Ti prego in ginocchio: Dammi un indirizzo M$ al quale rispondano umani.
Te ne sarei veramente molto grato!

 Debug.Print Abs(Fix(c) - c)
Luca, OK, ma se il numero è 5.12345 (e non dimenticare il 5 finale)???
Il Currency lavora al max su 4 decimali.

 Il Currency lavora al max su 4 decimali.
Infatti la tua risposta sull'arrotondare e' assolutamente corretta.
Piu' che suggerire il Currency come soluzione, che peraltro e' perfettamente
lecita perche' il risultato viene appunto arrotondato e non troncato, volevo
far notare che funziona come ci si aspetta solo laddove la virgola non e'
mobile, mentre negli altri casi e' un comportamento abbastanza normale (per
quel genere di operazioni)
Certo non e' motivo per chiamare l'assistenza MS ;-)


 Certo non e' motivo per chiamare l'assistenza MS ;-)
Luca, concedimi uno sfogo: Siamo nel 2002, andiamo da anni (così pare,
almeno) sulla Luna e stiamo progettando di andare su Marte. Mi chiedo (e ti
chiedo): E' lecito pretendere che un computer sappia fare 30.7-30? Io credo
di sì e aggiungo: Se quei furboni di M$ (o di Intel, sarebbe meglio dire)
sanno che in certi casi ci sono degli errori di calcolo, perchè caspita non
ci pensano loro, a monte? Se in una query SQL l'apostrofo viene spesso
confuso come delimitatore e non come carattere contenuto in un campo, mi
chiedo e ti chiedo, che professionalità dimostra una grande (mamma mia
quanto è piccola, invece!) M$ che, perfettamente al corrente che sta
trattando un campo (lo sa, vero?), non ci pensa lei a interpretarlo
correttamente? Perchè se in VB scrivi a="Teatro dell'Opera" quell'apostrofo
non funge da inizio commento? Perchè, perchè, perchè???

 non funge da inizio commento? Perchè, perchè, perchè???
Perche' non e' ambiguo, in quanto i due separatori " e ' sono ben
distinti...
prova a scrivere a = "Teatro dell"Opera" oppure in una query SQL, per
l'appunto, WHERE Campo='Teatro dell'Opera' e dimmi come riesci (tu software,
non tu umano ;-) ) a distinguere quando finisce il campo di testo se la
regola e' "delimitato da apici"
Certo, puoi sempre creare un parser di stringhe SQL super cazzuto, ma ne
vale la pena? esiste uno standard da seguire, con una regoletta
semplicissima e lo conoscono tutti; preferisco vengano sprecati cicli di CPU
su qualcosa di piu' interessante che non su una procedura che deve
correggere le cose che scrivo...
Al massimo, in questo esempio, posso darti ragione se parli
dell'assegnazione
RecordSet.Fields(x) = "Teatro dell'Opera"
dove la routine property avrebbe potuto occuparsi da sola del raddoppio


 dove la routine property avrebbe potuto occuparsi da sola del raddoppio
Ecco, appunto, e fatta una volta è fatta per sempre. Anche se in questo caso
non è necessario...
Luca, scusami, ma sono arrabbiato (ovviamente non con te) e in questi
momenti vorrei essere un gelataio e non un programmatore.

 momenti vorrei essere un gelataio e non un programmatore.
Lo so, ci mancherebbe... eppoi mica stiamo litigando...
io al momento vorrei essere un barman; se col mio amico Antonio troviamo il
locale giusto, ti chiamiamo per l'angolo Gelati & Granite (sempre se non ti
hanno gia' preso al chiosco dei panini allo stadio) ;-)


 hanno gia' preso al chiosco dei panini allo stadio) ;-)
;-) Vedo che sei molto attento. Grazie della chiacchierata/sfogo. Buon
lavoro.

Te ne sarei gratissimo
Cerco di esserti utile citando un mio vecchio post che potrebbe fare 
al caso tuo:
<citazione>
Come giustamente rilevato, le limitazioni dei tipi in virgola mobile
sono fisiche e non dipendono dalla follia di qualche ingegnere
dell' Intel.
Su MSDN ci sono tre articoli che aiutano a schiarirsi le idee ed
approfondiscono i concetti gia' esposti da danilo e Mauro:
1.
HOWTO: Work Around Floating-Point Accuracy/Comparison Problems 
Q69333
http://support.microsoft.com/support/kb/articles/Q69/3/33.ASP
da cui estraggo questo incipit:
To reliably test whether two floating-point variables or expressions are equal 
(using IEEE format or MBF), you must subtract the two variables being compared 
and test whether their difference is less than a value chosen at the limits 
of significance for single or double precision. 
NO OTHER TEST FOR EQUALITY WILL BE RELIABLE. 
2.
INFO: IEEE Floating-Point Representation and MS Languages 
Q36068
http://support.microsoft.com/support/kb/articles/Q36/0/68.ASP
3.
(Complete) Tutorial to Understand IEEE Floating-Point Errors 
Q42980
http://support.microsoft.com/support/kb/articles/Q42/9/80.ASP
 hth, hal
</citazione>
-- 
hth, hal

 sanno che in certi casi ci sono degli errori di calcolo, perchè caspita
Per una volta: ma cosa cavolo c'entrano M$ e Intel?
Lo standar SQL viene deciso da un comitato superpartes, e le specifiche dei
numeri virgola mobile (IEEE) anche (o forse dalla Sun, dove queste
specifiche sono visionabili).
Prenditela quindi con queste entità astratte, piuttosto che sprecare i soldi
del telefono con la M$ (che non farebbero altro che riderti in faccia per la
tua richiesta, e avrebbero ragione).
Il problema di SQL non esiste.
Il problema di IEEE è (se ci pensi bene) un falso problema.
Come puoi rappresentare con una simbologia finita (32 bit) un numero che
potrebbe essere teoricamente infinito?
Ciao

 per rappresentare i numeri decimali in formato binario.
chi è che diceva "siamo esseri analogici intrappolati in un mondo digitale
che noi stessi abbiamo creato"?
Ciao

 a=Teatro dell'Opera
Quindi se uno scrive
Dim a as String
a=Calcolo
in realtà vuole assegnare ad a la parola "Calcolo" (vedi? le virgolette si
usano anche in lingua parlata :)) e non il risultato della funzione
Calcolo()?
Ciao

che noi stessi abbiamo creato"?
Donald Norman:  Il computer invisibile 
Ma, comunque, anche la logica ha le sue belle limitazioni:
ricordi Goedel?
-- 
ciao, hal

 ha scritto nel messaggio
news:3cb2...@news.cis.it...

Zanna, io chiaramente esageravo, ma ... come mai hai scritto Calcolo seguito
da parentesi?
Ora, scherzando ancora, ma non troppo, io credo che M$ avrebbe potuto/dovuto
semplificare il lavoro del programmatore, ove possibile, ovviamente. Io
credo che in molti casi sarebbe stato possibile. Tu no? ;-)))

credo che in molti casi sarebbe stato possibile. Tu no? ;-)))
Il Visual Basic e' una splendida prova di semplificazione della vita
del programmatore. Hai mai provato a scrivere un' applicazione
Windows non HelloWorld anche solo con l' SDK?
-- 
ciao, hal

 potrebbe essere teoricamente infinito?
I numeri che potrebbero essere teoricamente infiniti non possono essere
trattati, nè' dal PC, nè (almeno dal mio cervello) dagli umani. 30.7 - 30
non mi pare che presuma calcoli particolari. Era un esempio. La mia idea di
principio è sempre quella: Molte cose sarebbero semplificabili; M$, molto
spesso, ha deciso di lasciare a noi (ogni volta, bada bene) questo lavoro.
Ciao (sempre col sorriso, ovviamente) ;-)))

 ha scritto nel messaggio
news:a8ugj1$vgml8$1...@ID-56381.news.dfncis.de...

No, nč mai proverň (perň so cosa vuol dire programmare in linguaggio
macchina, ben prima di un funzionalissimo Assembler, altri tempi; allora
potevi aprire la macchina e con una matita dire: "Ecco, la mia variabile sta
esattamente in questo decimo di millimetro"). Hai ragione, Hal, ma io ho
torto se dico che si poteva fare di piů e/o meglio?

torto se dico che si poteva fare di piů e/o meglio?
Tutto e' migliorabile, ma non sempre le cose sono facili come sembrano.
Pensa soltanto alla diversita' di hardware sui quali deve girare un sistema
operativo per pc ed alle diverse culture a cui detto sistema operativo
deve adattarsi: secondo me in casa m$ sono anche fin troppo bravi.
-- 
ciao, hal

 ha scritto nel messaggio
news:hBis8.1338$SR5....@twister1.libero.it...

Non è colpa della Microsoft se i programmatori fossero quelli di una volta
cioè quelli che sanno cosa effettivamente sia un calcolo in virgola mobile o
se avessere qualche nozione di calcolo numeri capirebbero che non c'è nulla
da fare per come è fatto il computer il risultato è quello.
Hai solo bisogno di più precisione!!!!!!!!!!!!

 ha scritto nel messaggio
news:IDzs8.5182$SR5.1...@twister1.libero.it...

Non riesco proprio a capire perchè la colpa deve essere della M$.
La gente si lamenta quando un programma è lento, e la colpa di chi è della
M$,
si lamenta perchè il programma occupa troppa memoria, e la colpa di chi è?
della M$.
Chi di noi dopo aver scritto un programma lo rivede sostiutendo ai long
gli integer dove necessario oppure usa dei boolean invece di stringhe da un
carattere
o dei byte?
Io penso pochissimi.
Inoltre non riesco a capire perchè la M$ dovrebbe arrotondare il valore
dell'espressione.
Arrotondare è una parola molto grossa, per questo motivo insisto che un
programmatore
dovrebbe fare un piccolo corso di calcolo numerico.
Ho visto programmatori molto più esperti di me perdere ore proprio su
arrotondamenti
e grandezza delle variabili.
1) Se fosse facile programmare io perderei il lavoro
2) Tutto in informatica ed elettronica è un compromesso quindi se non è
stato
    fatto di più un motivo un motivo ci sarà
3) Perchè è colpa della M$ se usi un compilatore Borland succede la stessa
cosa.
                                    danilo

 deve adattarsi: secondo me in casa m$ sono anche fin troppo bravi.
Sono daccordissimo , e se ci pensate il VB e' fin troppo "unamo" e poco
"binario" , questo e' gia abbastanza , a volte il VB non e' vicino agli
Umani come vorremmo e a volte non e' vicino alla macchina come vorremmo !
Per me il VB e' una "quasiPerfetta" via di mezzo per permettere alla nostra
mente di creare qualsiasi cosa !
se poi 30,7 - 30 non fa 0,7 e' perche' il programmatore ha la possibilita'
di gestire il risultato il lungo e largo , quindi se voglio che mi dia 0,7
basta usare una funzione Round , oppure ( non so quando possa servire )
trattare il dato 0.6999~9 come voglio !

 M$,
[snip]
sai com'č, una volta che ti sei fatto il nome ;))
scherzi a parte, sono d'accordo con te su come questa sia una pratica
insulsa (alla microsoft non sono un branco di stinchi di santo, ci
mancherebbe altro...) ma il voler ricondurre tutto in "č colpa della
microsoft" senza starci a pensare su piů di tanto, evidenzia la pochezza di
chi posta simili questioni;
quando poi il tema del post riguarda la stra-discussa e arcinota questione
dei problemi di arrotondamento dovuti alla rappresentazione interna dei
numeri reali - e quindi dello standard IEEE - c'č proprio da farsi cadere le
braccia;
ciao

 ha scritto nel messaggio
news:a8v6ld$vebgg$1...@ID-92828.news.dfncis.de...

Sono una pochezza e mi cadono spesso le braccia. ;-))) (triplo sorriso, ma
confermo)