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.NET Discussion :

Résultats d'une conversion pas toujours corrects


Sujet :

VB.NET

  1. #1
    Membre à l'essai
    Inscrit en
    Février 2013
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 43
    Points : 11
    Points
    11
    Par défaut Résultats d'une conversion pas toujours corrects
    Bonsoir,

    Dans mon 2ème projet, je réalise une mise à l'échelle/réduction, mais voilà les résultats des conversions sont parfois incorrects (exemple : 30 -----> 18, 18------>30, 50----->30, 30------>50 etc...) pour l'instant le logiciel à fait de bonnes conversions, mais parfois il fait des conversions approximatives comme (56------->33, 33-------->55) cette exemple montre que le logiciel a fait une conversion approximative (il devait convertir 33----->56 normalement)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    Public Class Form1
        Public num As Integer
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If TextBox1.Text <> "" And TextBox2.Text <> "" And num = 0 Then
                TextBox4.Text = TextBox2.Text * 60 / 100
                TextBox3.Text = TextBox1.Text
                TextBox5.Text = (TextBox4.Text - Math.Truncate(Val(TextBox4.Text))) * 0.6
                TextBox5.Text = Math.Round(Val(TextBox5.Text), 5) * 100
                TextBox4.Text = Math.Truncate(Val(TextBox4.Text))
            Else
                If num = 0 Then
                    MsgBox("Une ou plusieurs valeurs restes à déterminer !", MsgBoxStyle.Critical, "Erreur!")
                End If
            End If
            If TextBox3.Text <> "" And TextBox4.Text <> "" And TextBox5.Text <> "" And num = 1 Then
                TextBox1.Text = TextBox3.Text
                TextBox2.Text = TextBox4.Text / 60 * 100
                TextBox2.Text = Math.Round(Val(TextBox2.Text))
                TextBox2.Text = Math.Truncate(Val(TextBox2.Text))
            End If
        End Sub
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            If num = 0 Then
                Timer1.Start()
                Timer2.Stop()
            End If
            If num = 1 Then
                Timer1.Stop()
                Timer2.Start()
            End If
        End Sub
     
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            TextBox3.ReadOnly = False
            TextBox4.ReadOnly = False
            TextBox5.ReadOnly = False
            TextBox1.ReadOnly = True
            TextBox2.ReadOnly = True
            num = 1
        End Sub
     
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            TextBox3.ReadOnly = True
            TextBox4.ReadOnly = True
            TextBox5.ReadOnly = True
            TextBox1.ReadOnly = False
            TextBox2.ReadOnly = False
            num = 0
        End Sub
    End Class
    Voilà en espérant que vous pourrez m'éclairer sur le soucis ^^

  2. #2
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Déjà en activant Option Strict ça éviterait toutes les conversions implicites restrictives (donc potentiellement destructrices d'informations).
    Après les opérations sur les flottants y'a toujours un seuil minimum de précision et pour des calculs les plus exacts possibles dans ce type de cas de figure il faut utiliser le type Decimal plutôt
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  3. #3
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    En même temps, vu le contexte, tu auras forcément des approximations.

    Tu pars d'entiers, que tu multiplies/divises par 0.6 et tu tronques/arrondis pour avoir à nouveau des entiers. Il y a donc perte d'information. Ce n'est alors pas étonnant que la conversion inverse ne donne pas toujours le résultat initial.

    Pour pouvoir faire la conversion dans les 2 sens, il faut que ta transformation soit bijective. Ce n'est pas le cas ici.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  4. #4
    Membre à l'essai
    Inscrit en
    Février 2013
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Déjà en activant Option Strict ça éviterait toutes les conversions implicites restrictives (donc potentiellement destructrices d'informations).
    Après les opérations sur les flottants y'a toujours un seuil minimum de précision et pour des calculs les plus exacts possibles dans ce type de cas de figure il faut utiliser le type Decimal plutôt
    Ta solution ne marche visiblement pas ^^

    En même temps, vu le contexte, tu auras forcément des approximations.

    Tu pars d'entiers, que tu multiplies/divises par 0.6 et tu tronques/arrondis pour avoir à nouveau des entiers. Il y a donc perte d'information. Ce n'est alors pas étonnant que la conversion inverse ne donne pas toujours le résultat initial.

    Pour pouvoir faire la conversion dans les 2 sens, il faut que ta transformation soit bijective. Ce n'est pas le cas ici.
    Ta solution m'intérésse pourrais-tu m'en dire plus ?

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 697
    Points
    10 697
    Billets dans le blog
    21
    Par défaut
    Ta solution m'intérésse pourrais-tu m'en dire plus ?
    Mais je n'ai pas de solution. Je pointe seulement les problèmes de ta proposition initiale

    Sehnsucht a proposé quelque chose, et je suis d'accord avec lui. C'est d'ailleurs ce que j'aurais proposé s'il ne l'avait déjà fait. Donc plutôt que de dire que sa solution ne fonctionne pas, donne nous le code que tu as fais et qui ne te satisfait pas. On pourra te dire ce qui ne va pas.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  6. #6
    Membre à l'essai
    Inscrit en
    Février 2013
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    Public Class Form1
        Public num As Integer
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If TextBox1.Text <> "" And TextBox2.Text <> "" And num = 0 Then
                TextBox4.Text = Convert.ToDecimal(TextBox2.Text) * 60 / 100
                TextBox3.Text = Convert.ToDecimal(TextBox1.Text)
                TextBox5.Text = (TextBox4.Text - Math.Truncate(Val(TextBox4.Text))) * 0.6
                TextBox5.Text = Math.Round(Val(TextBox5.Text), 5) * 100
                TextBox4.Text = Math.Truncate(Convert.ToDecimal(TextBox4.Text))
            Else
                If num = 0 Then
                    MsgBox("Une ou plusieurs valeurs restes à déterminer !", MsgBoxStyle.Critical, "Erreur!")
                End If
            End If
            If TextBox3.Text <> "" And TextBox4.Text <> "" And TextBox5.Text <> "" And num = 1 Then
                TextBox1.Text = Convert.ToDecimal(TextBox3.Text)
                TextBox2.Text = Convert.ToDecimal(TextBox4.Text) / 60 * 100
                TextBox2.Text = Math.Round(Convert.ToDecimal(TextBox2.Text))
                TextBox2.Text = Math.Truncate(Convert.ToDecimal(TextBox2.Text))
            End If
        End Sub
        Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
            If num = 0 Then
                Timer1.Start()
                Timer2.Stop()
            End If
            If num = 1 Then
                Timer1.Stop()
                Timer2.Start()
            End If
        End Sub
     
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            TextBox3.ReadOnly = False
            TextBox4.ReadOnly = False
            TextBox5.ReadOnly = False
            TextBox1.ReadOnly = True
            TextBox2.ReadOnly = True
            num = 1
        End Sub
     
        Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
            TextBox3.ReadOnly = True
            TextBox4.ReadOnly = True
            TextBox5.ReadOnly = True
            TextBox1.ReadOnly = False
            TextBox2.ReadOnly = False
            num = 0
        End Sub
    End Class

  7. #7
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Avant de dire qu'une "solution" (même si je n'ai jamais prétendu qu'il en s'agissait d'une) ne fonctionne pas il faudrait déjà l'appliquer ; rien qu'à voir ton dernier extrait de code je sais qu'Option Strict n'est toujours pas activé sinon ça compilerait pas tel quel.
    Et non, juste mettre Option Strict à On ne résoudra pas magiquement le problème ; par contre ça permettra de faire du code plus "propre" et donc d'éliminer toute une catégorie de désagréments qui eux peuvent avoir un impact sur la résolution de celui-ci.

    Après comme l'a dit dorinf ; faut pas t'étonner de perdre de l'information alors que tu tronques tes valeurs 56 * 0.6 ça fait 33.6 si tu le tronques à 33 et que tu le divises par 0.6 ça fait 55 du coup les résultats que tu obtiens initialement sont corrects (d'un point de vue code) ; mais pas ceux que tu souhaites (ce qui sont 2 choses différentes)

    Maintenant si tu as besoin de garder la valeur exacte pour le besoin des calculs garde la valeur exacte, rien ne t'empêche de la formatter pour un affichage plus "user-friendly" mais ce sont 2 choses indépendantes (chose qui manque cruellement à ce code également où logique d'affichage et logique métier [de calcul] se mêlent et rendent les choses plus confuses qu'elles ne sont)
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  8. #8
    Membre à l'essai
    Inscrit en
    Février 2013
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Je te confirme que Option Strict est à ON

  9. #9
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    shayw tu devrais éditer ton post pour bien citer (utiliser la balise quote) ; là on dirait que tu confirmes sa confirmation au lieu de juste le citer puis lui répondre ; ça peut prêter à confusion pour de futurs lecteurs
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  10. #10
    Membre à l'essai
    Inscrit en
    Février 2013
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Aucune erreur au moment du debogage du projet.

  11. #11
    Membre éprouvé

    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations forums :
    Inscription : Mars 2012
    Messages : 691
    Points : 929
    Points
    929
    Par défaut
    Citation Envoyé par Fundu31 Voir le message
    Je te confirme que Option Strict est à ON
    si c'est le cas alors tu dois avoir une liste d'erreurs

    tu peux assigner seulement une valeur de type string à textbox.text
    donc

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TextBox4.Text = Convert.ToDecimal(TextBox2.Text) * 60 / 100
    est incorrecte

    Tu devrais faire tes calculs avec des variables

  12. #12
    Membre éprouvé

    Homme Profil pro
    Inscrit en
    Mars 2012
    Messages
    691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Israël

    Informations forums :
    Inscription : Mars 2012
    Messages : 691
    Points : 929
    Points
    929
    Par défaut
    Citation Envoyé par Fundu31 Voir le message
    Aucune erreur au moment du debogage du projet.
    Si option strict et option explicit sont activés
    regarde avant de debogger
    la ligne
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TextBox4.Text = Convert.ToDecimal(TextBox2.Text) * 60 / 100
    doit etre souligné d'une trait ondulé
    ainsi toutes tes autres lignes
    Nom : error.png
Affichages : 202
Taille : 3,5 Ko

  13. #13
    Membre chevronné
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Points : 2 209
    Points
    2 209
    Par défaut
    Bref, on va pas épiloguer 10 ans sur Option Strict, c'est stérile

    Ton problème c'est que tu penses que ceci est vrai : Formule mathématique
    Ça ne peut être vrai que si la valeur à tronquer l'est déjà en fait ; autrement dit si Formule mathématique est une valeur entière
    Dans ton exemple (56) le résultat est 33.6 donc forcément en le tronquant tu perds le 0.6 et Formule mathématique il est là ton écart

    Moralité ; garde une valeur exacte pour tes calculs (stockée où ça te chante) et affiche ce résultat exact de la manière qui te convient le mieux (tronqué par exemple) mais ne mélange pas calcul et affichage
    Nous sommes tous plus ou moins geek : ce qui est inutile nous est parfaitement indispensable ( © Celira )
    À quelle heure dormez-vous ?
    Censément, quelqu'un de sensé est censé s'exprimer sensément.

  14. #14
    Membre à l'essai
    Inscrit en
    Février 2013
    Messages
    43
    Détails du profil
    Informations forums :
    Inscription : Février 2013
    Messages : 43
    Points : 11
    Points
    11
    Par défaut
    Je n'ai pas cette erreur là.
    Je vous mets à disposition mes options :
    http://image.noelshack.com/fichiers/...81-capture.png

Discussions similaires

  1. Une macro pas toujours rapide
    Par corent2 dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 14/04/2014, 18h28
  2. Champ pas toujours renseigné dans une table
    Par Boubas1 dans le forum Modélisation
    Réponses: 1
    Dernier message: 12/05/2007, 06h57
  3. Réponses: 3
    Dernier message: 16/03/2007, 18h04
  4. Réponses: 4
    Dernier message: 26/05/2006, 08h59
  5. Fonction ne retournant pas toujours une valeur
    Par mastochard dans le forum C
    Réponses: 14
    Dernier message: 25/05/2006, 12h13

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