Newsgroup: it.comp.lang.visual-basic
Titolo: [?] [Bug di VB] Condizione Do while con un Double

Qualcuno mi sa spiegare perchè se faccio un ciclo che ha come condizione la
verifica di uguaglianza di un double,
la cosa non funziona?
Provare questo codice:
Public Sub Funzione_calcolo()
 Const TX As Double = 0.15
 Dim T As Double
  T = 0
  TX = 0.15
  Do While (T <= TX)
   Debug.Print T, TX
   T = T + 0.015
  Loop
 Debug.Print T, TX
 Debug.Print (T = TX)
 If T = TX Then Debug.Print "OK"
End Sub

Nel codice che ho inviato ho inserito una riga che non c'entra.
L'assegnazione alla costante l'avevo utilizzata per provare la condizione
con due variabili.
Tolta comunque la riga TX=0.15, il problema rimane.
Perchè mai non funziona?
Ciao a tutti
Emanuele
codice corretto:
 Public Sub Funzione_calcolo()
  Const TX As Double = 0.15
  Dim T As Double
   T = 0


   TX = 0.15


 Nel codice che ho inviato ho inserito una riga che non c'entra.
ebbene si... credo proprio si tratti di un bel bacone bello grosso...
ho fatto un po' di prove... (ho VB6 SP4)
be'...
utilizzando questa funzione :
Private Sub Command1_Click()
  Dim X As Double
  Dim T As Double
  X = 0.15
   T = 0
   Do While (T <= X)
      T = T + 0.015
      DoEvents
   Loop
   Debug.Print T, X
   Debug.Print (T = X)
   If T = X Then Debug.Print "OK"
End Sub
nella finestra di debug trovo :
 0.15          0.15
False
cambiando le dichiarazioni da duoble a single ottengo invece :
 0.165         0.15
False
la cosa inqueitante non è tanto la condizione do while che funziona in modo
diverso...
quando il fatto che l'istruzione
If T = X Then Debug.Print "OK"
risulti falsa quando l'ide visualizza per entrambe le variabili un valore di
0,15
p.s. ho provato anche a cambiare le impostazioni internazionali per il
comma.... non è cambiato nulla
mah...
Ciao
Enrico

 [cut]
ok... ma perche' mai ho necessita di dichiarare anche l'incremento double???
insomma... io gli dico T = T + 0.015 e lui si perde qualche infinitesimo per
strada...
non è carino...
--
Ciao,
Enrico


tra l'altro anche cosi' continua a non funzionare....
Private Sub Command1_Click()
  Dim X As Double
  Dim T As Double
  Dim INCR As Double
  INCR = 0.015
  X = 0.15
   T = 0
   Do While (T <= X)
    T = T + INCR
    DoEvents
   Loop
  Debug.Print T, X
  Debug.Print (T = X)
  If T = X Then Debug.Print "OK"
End Sub
finestra di debug:
 0.15          0.15
False

Ho provato anche a scrivere su file,  a compilare il progetto ma il problema
rimane sempre...
Ciao
Emanuele


non è un bug, si tratta di double, cioé di numeri con "precisione". E'
difficile utilizzare confronti stretti di uguaglianza.
Option Explicit
Const delta As Double = 0.00000015  'piccolo a piacere
Sub main()
Funzione_calcolo
End Sub
Public Sub Funzione_calcolo()
 Const TX As Double = 0.15
 Dim T As Double
  T = 0
  'TX = 0.15
  Do While (T <= TX)
   Debug.Print T, TX
   T = T + 0.015
  Loop
 Debug.Print T, TX
 'Debug.Print (T = TX)
 Debug.Print Abs(T - TX) < delta
 If Abs(T - TX) < delta Then Debug.Print "OK"
End Sub
ciao
  Giovanni


Perchè sommando 0,015 a un double li fai perdere la sua "essenza" di double,
pur rimanendo una variabile di tipo double.
Tant'è vero che se scrivi
debug.print cSng(T)=cSng(TX)
 trasformando esplicitamente i valori in Single, anzichè implicitamente come
fai tu, la func restituisce True
ciao
ugo

 wrote in message
8r0hfg$ljr$1...@pegasus.tiscalinet.it...







Ok, ma se tu parti da valori con doppia precisione, permettendoti di
eseguire correttamente le iterazioni di calcolo, e testi i valori in singola
precisione, per evitare i noti problemi di arrotondamento, il problema si
supera.
O meglio:
Public Sub Funzione_calcolo()
    Dim TX As Double
    Dim T As Double
    TX = 0.15
    Do While (T < TX)
        Debug.Print T, TX
        T = T + 0.015
    Loop
    Debug.Print T, TX
    Debug.Print T= TX        'falso
    Debug.Print (CSng(T) = CSng(TX))        'vero
    If T = TX Then
        Debug.Print "OK"        'falso
    ElseIf CSng(T) = CSng(TX) Then
        Debug.Print "Eccoci"        'vero
    End If
End Sub
ciao
(il C, da questo punto di vista, è un'altra cosa.)
riciao
ugo