Newsgroup: it.comp.lang.visual-basic
Titolo: problemuccio con un calcolo

qualcuno sa dirmi come mai se scrivo:
Dim X, Y
X = 7E+16
Y = X + 1
Debug.Print X - Y
il risultato č ZERO ??!!??!!
come si puo evitare tutto cio?
esistono delle librerie che permettono di gestire, da VB, calcoli con numeri
cosi grossi ?
grazie
Ugo

 Debug.Print X - Y
Qui sottrai due numeri identici quindi...
Dove possibile dovresti cercare di prevedere i possibili calcoli e, prima
fare tutti quelli con i numeri "grandi" poi quelli con i numeri piccoli... o
viceversa...
Se la cosa ti sta stretta puoi usare delle funzioni che avevo postato che ti
permettono di fare semplici calcoli (somma, sottrazione, divisione,
moltiplicazione) con NUMERI INTERI con significatività fino a 2 miliardi
cifre (in base dieci). Attenzione, non garantisco per quel codice e
sicuramente é molto lento. Usa un sistema che sostanzialmente é il sistema
"umano" (ragiona come un bambino delle elementari). Non sarà difficile
estendere i ragionamenti anche a numeri con la virgola se necessario... ;)
I post vecchi li trovi su google:
http://groups.google.com/advanced_group_search
Il mio post in questione é:
http://groups.google.com/groups?hl=it&rnum=2&selm=9iend7%24ifa1a%241%40ID-67
444.news.dfncis.de
                Ciao
                                    Allanon

>>>> "DH" == Delta Hug <xx@xx.x> writes:
DH> qualcuno sa dirmi come mai se scrivo:
DH> Dim X, Y
DH> X = 7E+16
DH> Y = X + 1
DH> Debug.Print X - Y
DH> il risultato č ZERO ??!!??!!
Ci  sono due  problemi.  Il  primo  č che  la dichiarazione  Dim X,  Y
dichiara due  variant. Il tipo variant  č una cosaccia  che puň tenere
valori di tipo diverso e nel  tuo caso credo che rappresenti 7E16 come
un single (32 bit,  di cui 1 di segno 8 di esponente e  24 :) - con un
trucco - di mantissa).
Il secondo  č che La rappresentazione  dei numeri in  virgola mobile č
per forza  approssimata in quanto  conservi solo le cifre  binarie piů
significative  (la prima cosa  che insegnano  a calcolo  numerico): ad
esempio 7E16 viene rappresentato in un double come
                 (1)<--- Qui c'č il trucco
0 0000000000110111 11110001011000010100001000011100100011000000000
[Il trucco č questo: si sceglie l'esponente di 2 che garantisca che il
 primo bit rappresentato č un 1, e a questo punto dato che vale sempre
 1 nemmeno lo si tiene scritto in memoria]
 
O in modo un po' piů leggibile
1.11110001011000010100001000011100100011 * 2^55
Se esamini la  prima scrittura di 7E16 in binario ti  accorgi che lo 0
piů a destra  corrisponde a 2^8, quindi 1 č  troppo piccolo per essere
considerato dall'approssimazione.
DH> come si puo evitare tutto cio?
Usualmente  usando  librerie che  usino  rappresentazioni piů  estese.
Strano a dirsi č quasi piů  facile farle in linguaggio macchina che in
un linguaggio ad alto livello.
In VB a 32 bit potresti usare una serie di variabili di tipo integer e
trappare gli overflow nelle somme per propagare il carry.
Per le moltiplicazione la cosa č  piů tosta e devi usare dei long come
accumulatori per le moltiplicazioni.
Gian Uberto Lauri               "Bloody instructions which, being taught, 
sa...@eng.it
                     return to plague their inventor" 
C.so Stati Uniti 23              ("Macbeth", Atto 1, Scena 7; Hacker Jargon
Tel: 
+39 049 828 3556
             File 4.0.0, voce: Programming, 1)