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 :

Incompréhension Calcul Double


Sujet :

VB.NET

  1. #1
    Candidat au Club
    Inscrit en
    Avril 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 4
    Points : 4
    Points
    4
    Par défaut Incompréhension Calcul Double
    Bonjour à toutes et à tous,

    Je réalise une application sous Visual Basic Express 2010.
    je me retrouve face à une incompréhension que je ne sais expliquer.

    Pour les besoins d'une application d'étalonnage, je dois générer une liste de points(valeur Physique,valeur électrique)

    Pour mes tests, je génère mon propre tableau de points.

    En fait pour ranger ces points et les traiter efficacement par la suite, je les range dans un dictionnaire (Double,Double) ou la valeur physique est la clé.
    je remplis mon dictionnaire comme ceci.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    For y As Integer = 1 To 2500                              
           Dico.Get_DicoPoints.Add(800 + y * 0.24, -5 + y * 0.004)
    Next
    Jusqu'ici il n'y a pas vraiment de soucis. Ces valeurs sont affichées dans un DataGridView.

    Nom : vbGridView.png
Affichages : 213
Taille : 10,6 Ko

    et ces valeurs affichées dans le DataGridView sont correctes

    Par contre j'ai analysé en détail (espion) l'ensemble clé, valeur et il y a un phénomène que je ne comprends pas.

    Certaines valeurs de clé sont incohérentes(de valeur aussi mais c moins grave):

    Si je prends la calculette 800+(567*0.24)=936.08
    Hors la valeur de clé de mon dictionnaire pour cet élément est:936.07999999999993....

    Clés du dictionnaire:
    Nom : ClésDictionnaire.png
Affichages : 197
Taille : 9,8 Ko

    Clés/Valeurs du dictionnaire:
    Nom : ClesValeurDictionnaire.png
Affichages : 171
Taille : 7,0 Ko

    Pourtant l'affichage dans le DataGridView est correct.

    Ce qui fait que quand je me sers de mes valeurs du DataGridView pour modifier certaines valeurs notamment les clés, la fonction remove du dictionnaire ne marche pas. Logique vu que la valeur du DataGrid ne correspond pas à la valeur de la clé dans mon dictionnaire.

    Voila j'espère avoir été assez clair.

    Si quelqu'un peut réussir à m'expliquer ce problème, je le remercie d'avance.

    ps: j'ai déjà trouvé une solution pour contourner le problème.

  2. #2
    Membre émérite Avatar de mactwist69
    Homme Profil pro
    Développement VB.NET
    Inscrit en
    Janvier 2007
    Messages
    1 707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Développement VB.NET
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 707
    Points : 2 528
    Points
    2 528
    Par défaut
    Bonjour,

    C'est un problème rencontré dans plusieurs langages.
    http://www.developpez.net/forums/d80...cation-double/

    La valeur stockée d'un double est parfois imprédictible, mais toujours proche de la vérité.
    La machine fait simplement des approximations très proche de la vérité.

    Plusieurs solutions s'offrent à toi :

    (Pour ces deux je ne suis pas sûr du résultat)
    - peut être essayer un autre type : Float...
    - faire la multiplication avec un entier (24 plutôt que 0.24) et diviser par 100

    - et la plus fiable à mon goût : Faire un arrondi !
    L'avenir appartient à ceux... dont les ouvriers se lèvent tôt. (Coluche)

  3. #3
    Expert confirmé Avatar de DonQuiche
    Inscrit en
    Septembre 2010
    Messages
    2 741
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 2 741
    Points : 5 485
    Points
    5 485
    Par défaut
    Citation Envoyé par popol5485 Voir le message
    Certaines valeurs de clé sont incohérentes(de valeur aussi mais c moins grave):

    Si je prends la calculette 800+(567*0.24)=936.08
    Hors la valeur de clé de mon dictionnaire pour cet élément est:936.07999999999993....
    Un nombre peut avoir une représentation exacte dans une base mais pas dans une autre. Ainsi 1/3 n'a pas de représentation exacte en base 10 (0.333333) mais en base 3 il s'écrit simplement comme 1*Base^-1. De la même façon 0.24 s'écrit comme 24*Base^-2 en base 10 mais il n'existe pas de représentation exacte en base 2. Le compilateur a donc utilisé la représentation la plus proche, d'où des erreurs visibles à certains endroits.

    Ce ne sont toutefois pas des erreurs d'arrondi, la fiabilité du calcul n'est pas en cause (l'erreur relative finale sera identique à l'erreur relative initiale). Ce sont seulement des erreurs de représentation. Si ces erreurs ne sont pas acceptables, alors il faut utiliser le type decimal, beaucoup plus lent mais dont la représentation interne est en base 10. Et s'il s'agit simplement d'une question d'interface utilisateur, un arrondi fera l'affaire.

  4. #4
    Expert confirmé
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Attention ce pendant. Si vous devez pratiquer des arrondis sur ces valeurs, vous risquez d'obtenir des résultats faussés (et peut-être avec d'autres opérations aussi... je n'ai pas vraiment creusé).

    Lorsqu'on arrondi, de 0 à 4, c'est vers le bas et de 5 à 9, vers le haut.

    Mais si maintenant pour une valeur vous avez un partie décimal de égale à 0.5, elle pourrait être stockée en float (ou double?) comme 0.499999999 (avec je ne sais pas combien de 9).

    Lors d'un round sur cette valeur, elle sera arrondie vers le bas et non vers le haut.

    Personnellement, si mes calculs doivent êtres précis, j'utilise toujours le type decimal (même s'il est plus lent) pour éviter ce genre de problème.
    Kropernic

  5. #5
    Candidat au Club
    Inscrit en
    Avril 2008
    Messages
    4
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 4
    Points : 4
    Points
    4
    Par défaut
    Merci pour toutes vos réponses.

    L'arrondi a 6 digit a réglé mon problème.

    Mais si maintenant pour une valeur vous avez un partie décimal de égale à 0.5, elle pourrait être stockée en float (ou double?) comme 0.499999999 (avec je ne sais pas combien de 9).

    Lors d'un round sur cette valeur, elle sera arrondie vers le bas et non vers le haut.
    Personnelement je n'ai pas vu ce genre de comportement.

  6. #6
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    si tu avais compris ce qu'on a dit tu aurais remplacé tes double par des decimal plutot que de faire un arrondi
    un decimal stocke la valeur exacte que tu lui donnes, un double stocke ce qu'il a envie qui est pas loin de ce que tu veux
    peu de développeurs travaillent avec des double (ou single), aucune banque etc...
    le seul avantage du double c'est d'être plus rapide pour du calcul, donc pour des jeux 3d ca passe en général
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Inactif  

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2012
    Messages
    4 904
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2012
    Messages : 4 904
    Points : 10 168
    Points
    10 168
    Billets dans le blog
    36
    Par défaut
    Bonjour,


    Citation Envoyé par Kropernic Voir le message
    Attention ce pendant. Si vous devez pratiquer des arrondis sur ces valeurs, vous risquez d'obtenir des résultats faussés (et peut-être avec d'autres opérations aussi... je n'ai pas vraiment creusé).

    Lorsqu'on arrondi, de 0 à 4, c'est vers le bas et de 5 à 9, vers le haut.

    Mais si maintenant pour une valeur vous avez un partie décimal de égale à 0.5, elle pourrait être stockée en float (ou double?) comme 0.499999999 (avec je ne sais pas combien de 9).

    Lors d'un round sur cette valeur, elle sera arrondie vers le bas et non vers le haut.

    Personnellement, si mes calculs doivent êtres précis, j'utilise toujours le type decimal (même s'il est plus lent) pour éviter ce genre de problème.
    Je suis allé faire un tour sur MSDN (Encore que c'est probablement dans l'aide, également) :

    http://msdn.microsoft.com/fr-fr/libr...aspx#Precision

    J'ai appris des choses intéressantes, comme l'énumération MidpointRounding, présente dans certaines surcharges. Cela permet d'influencer la façon dont le 5 est arrondi; soit en plus ou en moins, au nombre pair le plus proche; soit vers le nombre le plus éloigné de zéro. Quant aux surcharges sans MidpointRounding, l'arrondi du 5 est supposé être systématiquement au nombre pair, ou à la décimale paire (2,545 est arrondi à 2,54 ou 2,5; 2,535 est arrondi à 2,54; 22,35 est arrondi à 22,4; 21,5 est arrondi à 22; 22,5 est aussi arrondi à 22). Sauf que, comme vous l'avez si bien dit, les problèmes de précision, dans le cas du type Double, cet arrondi au pair le plus proche est quelque peu plus aléatoire.

    Comme quoi que l'on peut en apprendre à tous les jours, ou en "bon québécois" : "Je vais me coucher moins niaiseux ce soir".
    À ma connaissance, le seul personnage qui a été diagnostiqué comme étant allergique au mot effort. c'est Gaston Lagaffe.

    Ô Saint Excel, Grand Dieu de l'Inutile.

    Excel n'a jamais été, n'est pas et ne sera jamais un SGBD, c'est pour cela que Excel s'appelle Excel et ne s'appelle pas Access junior.

Discussions similaires

  1. [AC-2003] Calculer double tva
    Par ortiz dans le forum VBA Access
    Réponses: 19
    Dernier message: 20/06/2013, 08h21
  2. Résultat anormal lors de calcul Double
    Par totore dans le forum Langage
    Réponses: 8
    Dernier message: 04/12/2006, 00h45
  3. Réponses: 4
    Dernier message: 26/08/2006, 02h01
  4. Calcul String (valeur Hexa) -> double puis double -> char *
    Par ben_ghost dans le forum VC++ .NET
    Réponses: 5
    Dernier message: 30/07/2006, 21h04
  5. [Conversion]Probleme de calcul en double et en floatant
    Par TOPGUN89 dans le forum Général Java
    Réponses: 2
    Dernier message: 18/04/2005, 17h46

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