IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB 6 et antérieur Discussion :

Bug étrange sur du single


Sujet :

VB 6 et antérieur

  1. #1
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut Bug étrange sur du single
    bonjour,
    j'ai un problème étrange sur une petite appli VB6 que je développe :

    j'ai 2 variables A et B déclarées en Single
    dans mon programme j'ai la ligne suivante :

    If A <> B Then Msgbox "Hello"

    parfois, malgré que A = B, la ligne ci-dessus est tout de même exécutée et j'ai mon joli "Hello", et en debug A et B sont pourtant bien identiques ???

    mes variables sont déclarées en Public dans un module .bas , et mon programme tourne dans la forme principale form1

    si vous avez quelque piste que ce soit, je suis preneur !
    merci d'avance

  2. #2
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Par défaut
    Impossible, sauf si tu t'es mélangé les pinceaux quelque part avec A et B ...

  3. #3
    Membre Expert
    Avatar de zazaraignée
    Profil pro
    Étudiant
    Inscrit en
    Février 2004
    Messages
    3 174
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2004
    Messages : 3 174
    Par défaut
    Salut

    Est-ce que les fois où A = B il y aurait une possibilité pour que ce soit zéro, par hasard?

  4. #4
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    non, les valeurs sont des réels bien différents de zero
    je vais esseyer le programme sur une autre plateforme pour voir... je vous tiens au courant

  5. #5
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Par défaut
    Je ne crois pas que ce soit lié à la plateforme.
    Ton appli, plus surement !

  6. #6
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    exact,
    je viens de refaire le test sur win XP et win 2000, et le problème est toujours là
    si ça tente quelqu'un de jeter un oeil, sachant que c'est du vb6, je veux bien filler mon source, c'est un début d'appli graphique
    a+

  7. #7
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Par défaut
    Je crois qu'il suffira que tu montres uniquement les lignes dans lesquelles A et B sont concernées, que ce soit en déclaration, en modification ou en affichage...
    En précisant, si une valeur est attribuée à l'une ou à l'autre de ces 2 variables, d'où "vient" la valeur .

  8. #8
    Membre Expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Par défaut
    je propose de faire un arrondi des deux variables avant la comparaison, avec des singles, il peut y avoir des decimales tres minimes, non visibles sans examen attentif. Surtout si on pense avoir a faire a entiers

  9. #9
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    Citation Envoyé par Delbeke
    je propose de faire un arrondi des deux variables avant la comparaison, avec des singles, il peut y avoir des decimales tres minimes, non visibles sans examen attentif. Surtout si on pense avoir a faire a entiers
    qu'appelles-tu examen attentif ? pour voir leur valeur, j'y vais soit en debug soit j'affiche leur valeur dans un msgbox comme ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If A <> B Then
      MsgBox "A=" & Str(A) & vbCr & "B=" & Str(B) & vbCr & "A-B=" & Str(A - B)
    End If
    ça donne ceci :

    on voit bien que A=B et pourtant leur différence donne une valeur proche de 0
    y'a-t-il un moyen de voir plus précisément le contenu d'une variable de type single ?

  10. #10
    Membre expérimenté Avatar de BertrandA
    Inscrit en
    Août 2003
    Messages
    170
    Détails du profil
    Informations forums :
    Inscription : Août 2003
    Messages : 170
    Par défaut
    C'et la représentation IEEE d'un nombre réel qui est en cause.
    Ce n'est pas la faute de VB, le problème existe dans la plupart des langages.
    Tester l'égalité de 2 réels est souvent une mauvaise idée.

    Essaye éventuellement avec des types doubles, ils sont stockés sur 8 octet (2 fois plus précis).
    Mais ça ne lèvera pas l'incertitude. La solution c'est d'arrondir à une précision suffisante pour ton appli et éventuellement comme tu le fais ci-dessus, de tester l'égalité de chaînes et pas de réels.

  11. #11
    Expert éminent


    Profil pro
    Inscrit en
    Juin 2003
    Messages
    14 008
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 14 008
    Par défaut
    tiens j'ai joué et j'ai le même probléme que toi à l'oeil nu ils sont égaux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub tesst()
     Dim a As Single
     Dim b As Single
      b = 5.112299
      a = b + 4.768372 * 10 ^ -7
     If a <> b Then
      MsgBox "A=" & Str(a) & vbCr & "B=" & Str(b) & vbCr & "A-B=" & Str(a - b)
     End If
     End Sub
    [Edit] test avec double
    Citation Envoyé par BertrandA
    ..
    Essaye éventuellement avec des types doubles, ils sont stockés sur 8 octet (2 fois plus précis)....
    le résultat dans msgbox :
    A= 5.1122994768372
    B= 5.112299
    A-B= 4.76837199947511E-07
    on moins c'est visible..

  12. #12
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Par défaut
    Citation Envoyé par jmfmarques
    Je crois qu'il suffira que tu montres uniquement les lignes dans lesquelles A et B sont concernées, que ce soit en déclaration, en modification ou en affichage...
    En précisant, si une valeur est attribuée à l'une ou à l'autre de ces 2 variables, d'où "vient" la valeur .

  13. #13
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    Merci à tous pour votre aide !
    Sur conseil (obstiné mais juste ) de jmfmarques j'ai remonté la chaîne jusqu'à l'origine, et après plusieurs Sub imbriqués avec passage de A et B en ByRef, je suis tombé sur ceci :
    En fait j'utilise le .Tag d'un contrôle pour y stocker un réel (par souci de clareté et éviter ainsi la prolifération de variables temporaires), mais la reconversion en Single via CSng ne redonne pas exactement la même valeur qu'à l'origine, même si visuellement elle apparaît correcte.
    Le test est simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim A as Single, B As Single
    Randomize Timer
    A = Rnd
    Form1.Tag = A
    B = CSng(Form1.Tag)
    If A <> B Then MsgBox "A=" & Str(A) & vbCr & "B=" & Str(B) & vbCr & "A-B=" & Str(A - B)
    C'est donc la conversion Alpha => Single qui merde un peu, dommage.
    Bref, préférez des "vrai" variables plutôt qu'un intermédiaire douteux !
    Encore merci à tous.

  14. #14
    Membre Expert
    Avatar de Delbeke
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    2 675
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : France

    Informations forums :
    Inscription : Juillet 2006
    Messages : 2 675
    Par défaut
    ce n'est pas de l'alpha vers un single, mais variant vers single. le variant c'est tres pratique pour bien galérer lol
    la propriété tag d'un composant est stockée dans un variant (en interne)

  15. #15
    Inactif  
    Avatar de jmfmarques
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    3 784
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 3 784
    Par défaut
    Essaye, pour voir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Sub Command1_Click()
      Dim A As Single, B As Single
      Randomize Timer
      A = Rnd
      Form1.Tag = Str(A)
      B = CSng(Val(Form1.Tag)) 
      If A <> B Then MsgBox "A=" & Str(A) & vbCr & "B=" & Str(B) & vbCr & "A-B=" & Str(A - B)
    End Sub
    et dis...

  16. #16
    Membre averti
    Inscrit en
    Avril 2006
    Messages
    23
    Détails du profil
    Informations forums :
    Inscription : Avril 2006
    Messages : 23
    Par défaut
    Citation Envoyé par jmfmarques
    Essaye, pour voir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Private Sub Command1_Click()
      Dim A As Single, B As Single
      Randomize Timer
      A = Rnd
      Form1.Tag = Str(A)
      B = CSng(Val(Form1.Tag)) 
      If A <> B Then MsgBox "A=" & Str(A) & vbCr & "B=" & Str(B) & vbCr & "A-B=" & Str(A - B)
    End Sub
    et dis...
    j'ai esseyé, mais ça ne change rien

Discussions similaires

  1. Bug étrange sur un formulaire
    Par shelko dans le forum Langage
    Réponses: 1
    Dernier message: 19/09/2009, 11h05
  2. Bug étrange sur une ligne.
    Par ickylevel dans le forum Général Python
    Réponses: 1
    Dernier message: 20/02/2008, 21h46
  3. Erreur étrange sur recvfrom
    Par Gore dans le forum Développement
    Réponses: 2
    Dernier message: 17/02/2005, 12h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo