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 :

Imprécision dans les valeurs affichées par visual Studio ? [Débutant]


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut Imprécision dans les valeurs affichées par visual Studio ?
    Bonjour à tous,
    j'ai crée un programme pour calculer des rapports de vitesses d'un véhicule et j'ai quelque doute sur la précision des résultats sans toutefois en être certains (je veux juste m'assurer que je n'introduit pas d'erreurs d'arrondie ou d'imprécision dans mes calculs :
    Tout d'abord j'utilise des Single partout ou je pourrais avoir des chiffres à virgules...en me disant que cela me donne une précision suffisante (avec assez de chiffres significatifs) pour les valeurs que je souhaite afficher du style (253,612 km/h) par exemple.
    En voulant vérifier je m'appercois que les valeurs des variables affichées dans l'intellisense et dans l'onglet "Automatique" semble imprécise. Pourquoi 5.44444466 ???
    Pourquoi à priori on ne peux pas se fier à ces résultats ?
    Est ce que la valeur de 5.444445 est la représentation réelle du chiffre stocké en mémoire ? Il me semble que le type single est plus précis que ça...
    En faisant l'opération inverse je constate que le résultat attendue de 49 est strictement identique au chiffre de départ, autrement dit l'opération intermédiaire n'a introduit aucune approximation (et ça c'est une bonne chose), est ce un hazard ou doit t'on s'attendre à ce type de comportement quelque que soit le calcul ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Dim A As Integer
    Dim B As Integer
    Dim x As Single
    A = 49
    B = 9
    x = CSng(A / B) ' l'intellisense affiche x=5.44444466
    Debug.Print(CStr(x)) ' affiche 5.444445
    Debug.Print(CStr(B * x)) ' affiche 49 (le résultat final est correct)
    Beaucoup de question mais j’espère que vous pourrez m’éclairer un peu sur ces quelques points.

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Bon au final je n'ai aucun soucis avec mon programme, tous les calculs se font parfaitement.
    Je suis quand même intrigué par ce qu'affiche visual studio...si quelqu'un a une explication......

  3. #3
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut
    Bonjour,

    Dans VB.NET les calculs sur les flottants se font par défaut en Double

    Ainsi, dans ta parenthèse, ta division est faite en Double, avant d'être convertie en Single

    L'intelli-sense affiche probablement le résultat en Double

    Il est possible de forcer un nombre à être considéré comme un Single avec le caractère !

    https://msdn.microsoft.com/fr-fr/library/xay7978z.aspx

    Attention tous les calculs faits en Double ou en Single ne tombent pas juste (sauf si ce sont des puissances de 2, positives ou négatives)

    Tout le monde se doute que la valeur de PI ne peut être que approchée par un ordinateur

    Mais c'est plus vicieux, par exemple le nombre 0.3 a une écriture finie en décimal mais pas en binaire, il sera donc approché

    http://lslwww.epfl.ch/pages/teaching...ro/4.Reels.pdf

    Il faut toujours être conscient de cela, un algorithme "juste sur le papier" risque de ne pas fonctionner en pratique à cause des erreurs d'arrondi.

    Ainsi, il est très imprudent de tester si deux flottants sont égaux, car avec les erreurs d'arrondis ils risquent en pratique d'être toujours différents !

    Concrètement dans une boucle, si a et b sont des flottants, il faut faut jamais avoir une condition de fin "a = b" mais "a >= b" ou "a =< b" ou "a > b * 0.999 AND a < b * 1.001"

    Certains algorithmes dits "numériquement instables" sont extrêmement difficiles à implanter car la moindre petite erreur d'arrondi les fait planter.

    Des problèmes de maths "très bêtes" que l'on résout facilement à la main sont de vrais casses-têtes à implanter sous forme de code informatique... Au hasard : calcul de l'offset d'un polygone

    Si tu fais un programme contenant un peu de calculs cela vaut le coup de se pencher là dessus.

    Il faut également se méfier de la division par zéro

    Concrètement pour une équation de droite, on l'utilise pas
    y = a * x + b
    mais la version paramétrique :
    x = x1 + t * dx
    y = y1 + t * dy

    En effet si la droite est verticale (ou presque verticale) l'équation y = a * x + b n'est pas appropriée et va donner des plantages ou des erreurs énormes.

    De plus l'équation paramétrique est utile pour un segment de droite ; en posant
    dx = x2 - x1
    dy = y2 - y1
    et bien toutes les valeurs de t comprises entre 0 et 1 te donnent les points du segment X1,Y1 - X2,Y2
    si t = 0 le point est X1,Y1
    si t = 1 le point est X2,Y2
    si t < 0 le point est avant X1,Y1
    si t > 1 le point est après X2,Y2

    Les maths appliqués à l'informatique sont un peu spéciales et en tout cas différentes de celles qu'on utilise pour faire un calcul complet à la main avec des données chiffrées.

    Cherches avec Google "instabilité numérique" ou "analyse numérique" il y a pas mal de choses intéressantes à découvrir

    Il y a aussi des questions d'optimisation :
    une division coute plus cher en temps de calcul qu'une multiplication
    une multiplication coute plus cher en temps de calcul qu'une addition
    donc on précalcule les valeurs en dehors des boucles pour éviter d'avoir trop de division
    ou bien on adapte le calcul pour éviter d'avoir à diviser
    exemple : au lieu de comparer
    c = (a+d) / b
    compare plutôt
    c * b = a+d
    en plus on évite le plantage si b est égal à zéro

    A+

  4. #4
    Membre éclairé
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Mars 2012
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2012
    Messages : 640
    Par défaut
    Franchement merci, je ne m'attendais pas à avoir une réponse aussi complète....je fait en effet des comparaisons sur des single, d'ou mon inquiétude mais à priori tout se passe bien mais sans aucune certitude ni sans que je sache vraiment pourquoi....
    Je pense que ce pavé va intéresser pas mal de monde donc merci pour eux aussi....

  5. #5
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002
    Par défaut
    Citation Envoyé par BasicZX81 Voir le message
    Franchement merci, je ne m'attendais pas à avoir une réponse aussi complète....je fait en effet des comparaisons sur des single, d'ou mon inquiétude mais à priori tout se passe bien mais sans aucune certitude ni sans que je sache vraiment pourquoi....
    Je pense que ce pavé va intéresser pas mal de monde donc merci pour eux aussi....
    L'avantage des Single est la moindre occupation mémoire :
    - un Single est sur 32 bits, 4 octets
    - un Double est codé sur 64 bits, 8 octets

    Par contre les Singles sont beaucoup moins précis, et ne peuvent pas stocker des nombres très grands ou très proche de zéro.

    Single : la valeur est comprise entre -3,4028235E+38 et -1,401298E-45 pour les valeurs négatives et entre 1,401298E-45 et 3,4028235E+38 pour les valeurs positives

    Double : la valeur est comprise entre -1,79769313486231570E+308 et -4,94065645841246544E-324 pour les valeurs négatives et entre 4,94065645841246544E-324 et 1,79769313486231570E+308 pour les valeurs positives

    En pratique le calcul avec des Singles n'est pas plus rapide qu'avec des Double, aucun gain de se côté là ; pire, il faut avoir recours à des CSng ou CDbl partout...

    Bref le type Single est intéressant :
    - pour économiser de la RAM mais vu la quantité de mémoire des ordinateurs actuels il faut déjà manipuler de très grosses quantités de données ; en pratique on peut faire les calculs en Double puis stocker les résultats en Single dans un tableau ou une liste
    - pour économiser la taille des fichiers ; en pratique si la taille des fichiers est critique on peut travailler sur des Double mais sauvegarder en Single

    Attention à chaque conversion Single <-> Double il y a une erreur d'arrondi

    Bref, sauf contraintes particulières, toujours travailler en Double.

    Note : sur les anciens systèmes 16 bits et 32 bits le Single était plus rapide et l'occupation mémoire était vraiment critique.
    J'ai commencé la programmation sur Amiga 1200 en 1993 ; la machine avait un CPU cadencé à 14 Mhz, une mémoire vive de 2 Mo et un lecteur de disquette basse densité de 800ko comme stockage
    Puis j'ai eu en 1997 mon premier PC, Cyrix 133 Mhz, 16 Mo de RAM, 1 Go de disque dur, Windows 95 qui plantait tout le temps
    Bref les choses ont bien changées

  6. #6
    Membre chevronné Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    1 002
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 002

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/01/2012, 19h06
  2. Réponses: 11
    Dernier message: 19/10/2010, 14h50
  3. Réponses: 5
    Dernier message: 28/03/2010, 22h47
  4. [E03] - Modifier les valeurs affichées dans une listbox
    Par couistelle dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 10/03/2009, 13h46
  5. Réponses: 1
    Dernier message: 24/01/2008, 14h21

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