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

Dotnet Discussion :

Problème de conversion/cast


Sujet :

Dotnet

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de SoBaKa
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2006
    Messages : 242
    Par défaut Problème de conversion/cast
    Bonjour,

    Je viens vers vous suite à un problème un peu bizarre de conversion (et de cast) et j'aimerais bien comprendre pourquoi, surtout qu'aucun de mes collègues n'a la réponse :p

    Bon vu qu'un exemple vaut mieux qu'un long discours voici le problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    double value = 8.53;
    Console.WriteLine((int)(value * 100)); // affiche 852
    Console.WriteLine(Convert.ToInt32(value * 100)); // affiche 853
    Bon je peux comprendre qu'un cast c'est un risque de perte de précision, surtout de double => int, mais dans ce cas ci, on multiplie par 100 pour justement avoir un nombre qui peut être casté sans perte. (853.0 => (int) => 853)

    La seule chose que je peux voir, c'est que 8.53 ne serais pas réellement 8.53 mais quelque chose du genre 8.5299999... Mais la encore, au niveau debug, c'est 8.53 qui s'affiche...

    Donc si quelqu'un a une explication à me fournir ^^ Merci :p

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 197
    Par défaut
    Je crois que l'explication est la dedans
    Si au cours d'opérations binaires, l'un des opérandes est Double, l'autre opérande doit alors être de type intégral ou de type virgule flottante (Double ou Single). Si, avant d'effectuer l'opération, l'autre opérande n'est pas Double, il est alors converti en Double et l'opération est effectuée à l'aide d'au moins une précision et une plage Double. Si l'opération donne un résultat numérique, le type de ce résultat est alors Double.

    Les opérateurs à virgule flottante, y compris les opérateurs d'assignation, ne lèvent pas d'exceptions. Dans des cas exceptionnels, le résultat d'une opération en virgule flottante est zéro, infini ou NaN, comme indiqué ci-dessous :

    Si le résultat d'une opération en virgule flottante est trop petit pour le format de destination, le résultat de l'opération est alors zéro.

    Si le résultat d'une opération en virgule flottante est trop grand pour le format de destination, le résultat de l'opération est alors PositiveInfinity ou NegativeInfinity, en fonction du signe du résultat.

    Si une opération en virgule flottante n'est pas valide, le résultat de l'opération est alors NaN.

    Si un ou deux opérandes d'une opération en virgule flottante sont NaN, le résultat de l'opération est alors NaN.

    Souvenez-vous qu'un nombre à virgule flottante ne peut se rapprocher qu'approximativement d'un nombre décimal, et que la précision d'un nombre à virgule flottante détermine dans quelle mesure il se rapproche d'un nombre décimal. Même si 17 chiffres maximum sont gérés en interne, la précision de la valeur Double ne comporte par défaut que 15 chiffres décimaux. La précision d'un nombre à virgule flottante a plusieurs conséquences :

    Deux nombres à virgule flottante qui apparaissent égaux à un niveau de précision particulier peuvent ne pas être égaux parce que leurs chiffres les moins significatifs sont différents.

    Une opération mathématique ou de comparaison qui utilise un nombre à virgule flottante peut ne pas avoir le même résultat si un nombre décimal est utilisé, car le nombre à virgule flottante peut ne pas se rapprocher exactement du nombre décimal.

    Une valeur peut ne pas effectuer un aller-retour si un nombre à virgule flottante est impliqué. Une valeur est décrite comme effectuant un aller-retour si une opération convertit un nombre à virgule flottante d'origine dans une autre forme, si une opération inverse transforme la forme convertie en nombre à virgule flottante, et si le dernier nombre à virgule flottante est égal au nombre à virgule flottante d'origine. L'aller-retour peut échouer parce qu'un ou plusieurs chiffres moins significatifs sont perdus ou modifiés au cours d'une conversion.
    La seule chose que je peux voir, c'est que 8.53 ne serais pas réellement 8.53 mais quelque chose du genre 8.5299999... Mais la encore, au niveau debug, c'est 8.53 qui s'affiche...
    Donc tu as raison il est bien stocker 8.5299999..., c'est l'affichage qui t'affiche un beau chiffre rond

    Question que je me pose est ce qu'on fait bien d'utiliser des double?

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Je conseille fortement d'utiliser le type DECIMAL à la place (tout comme dans les bases de données).

    Il est bien plus lent pour les calculs, mais sa précision est "exacte".

    J'ai toujours considéré qu'il faut réserver les types float pour des traitement où on se moque d'avoir une valeur exacte, en contrepartie de forts besoins en termes de vitesse. Genre traitements graphiques (2D et surtout 3D) ou sonores, traitements dans l'espace, etc.
    Mais pour tout ce qui est argent, quantités, ou autres informations contractuelle ou qui doivent être saisies/affichées telles quelles, il faut éviter comme la peste les types à virgule flotante.

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par BenoitM Voir le message
    Question que je me pose est ce qu'on fait bien d'utiliser des double?
    Citation Envoyé par StringBuilder Voir le message
    Je conseille fortement d'utiliser le type DECIMAL à la place (tout comme dans les bases de données).
    Si les deux existent, c'est qu'ils ont tous les deux leur utilité, donc il n'y en a pas un meilleur que l'autre dans l'absolu... En gros, decimal est destiné aux calculs où on doit avoir une valeur exacte en base 10 (typiquement, des calculs financiers où on ne peut pas s'amuser à avoir des approximations dues à la représentation binaire). Par contre, pour des mesures physiques par exemple, on utilise plutôt double : ça n'a pas beaucoup de sens de vouloir absolument une valeur exacte en base 10, puisque de toutes façons la mesure n'est jamais exacte à la base, et que la représentation décimale est purement arbitraire et ne correspond à rien dans la réalité ; donc autant profiter de la rapidité du calcul en virgule flottante...

    @SoBaKa, pour ton problème, fais ce test :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Console.WriteLine(value * 100 == 853.0); // affiche false
    En fait, à cause des approximations de la représentation en virgule flottante, 8.53 * 100 ne donne pas exactement 853, mais une valeur très légèrement inférieure... Le cast en int tronque simplement la partie décimale, ce qui donne 852, alors que Convert.ToInt32 arrondit à l'entier le plus proche, soit 853

  5. #5
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Si les deux existent, c'est qu'ils ont tous les deux leur utilité, donc il n'y en a pas un meilleur que l'autre dans l'absolu...
    C'est bien ce que j'indique dans le reste de mon message :o
    Les virgules flottantes, c'est très bien pour du traitement du signal, ou pour tout ce qui est opérations dans l'espace, graphiques, sons, etc : on se cogne d'avoir 1 ou 1,00000000001, ça donnera la même chose. En revanche, le float est à bannir de tout ce qui est financier (et plus généralement, de tout ce qui est contractuel).

  6. #6
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Février 2003
    Messages
    2 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2003
    Messages : 2 197
    Par défaut
    Citation Envoyé par tomlev Voir le message
    Par contre, pour des mesures physiques par exemple, on utilise plutôt double : ça n'a pas beaucoup de sens de vouloir absolument une valeur exacte en base 10, puisque de toutes façons la mesure n'est jamais exacte à la base, et que la représentation décimale est purement arbitraire et ne correspond à rien dans la réalité ; donc autant profiter de la rapidité du calcul en virgule flottante...
    Humm tu crois que ceux qui ont mesuré que des neutrinos ont mis X secondes de moins que les photons peuvent se permettent des petites imprécisions?
    bon en même temps je pense pas qu'ils se limitent à 15 décimals

    Ce que je voulais dire c'est que l'utilisation des double est plutot à réserver à des usages spécifiques plutot que de reservé le décimal à des usages spécifiques

    Surtout que la vitesse gagné dans le calcul n'est peut-être pas l'élément le plus déterminant dans la plupart des applications

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    C'est bien ce que j'indique dans le reste de mon message :o
    Ca m'apprendra à pas lire jusqu'au bout

    Citation Envoyé par BenoitM Voir le message
    bon en même temps je pense pas qu'ils se limitent à 15 décimals
    Tout à fait...
    Mais de toutes façons, même leur mesure super précise n'est pas totalement exacte, et l'avoir en base 10 n'apporte rien de plus...


    Citation Envoyé par BenoitM Voir le message
    Ce que je voulais dire c'est que l'utilisation des double est plutot à réserver à des usages spécifiques plutot que de reservé le décimal à des usages spécifiques
    Bah en pratique le seul cas que j'ai vu où l'utilisation de decimal est indispensable, c'est pour les valeurs monétaires... pour tout le reste, double fait aussi bien l'affaire.

    Citation Envoyé par BenoitM Voir le message
    Surtout que la vitesse gagné dans le calcul n'est peut-être pas l'élément le plus déterminant dans la plupart des applications
    Ca dépend de ce que tu fais... si tu fais des calculs en masse, c'est important. Mais si tu fais juste une petite opération de temps en temps, c'est sûr que ça va pas faire une grosse différence.

    Pour donner un ordre d'idée, voilà les temps pour effectuer 100 000 000 multiplications :
    - double : 167 ms
    - decimal : 2013 ms
    Soit plus de 10 fois plus lent...

  8. #8
    Membre expérimenté
    Avatar de SoBaKa
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2006
    Messages
    242
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2006
    Messages : 242
    Par défaut
    Citation Envoyé par BenoitM Voir le message
    Souvenez-vous qu'un nombre à virgule flottante ne peut se rapprocher qu'approximativement d'un nombre décimal, et que la précision d'un nombre à virgule flottante détermine dans quelle mesure il se rapproche d'un nombre décimal.
    Question que je me pose est ce qu'on fait bien d'utiliser des double?
    Je pense que tu as la réponse grâce à ta citation également

    Le pire c'est que sur la plupart des sites e-commerce que j'ai du travailler c'est toujours le type double qui était utilisé... Pour moi pas de problèmes, vu que je préfère les conversions à la pratique du cast... Mais ceux qui cast en se disant "double vers entier, je suis certain à 100% d'avoir une valeur correcte", bah ils ont tort...

    Merci à toi pour ta réponse... et je pense que ça fait une bonne leçon de + pour moi.

    Citation Envoyé par StringBuilder
    Je conseille fortement d'utiliser le type DECIMAL à la place (tout comme dans les bases de données).
    Je suis plus ou moins d'accord avec toi sur le principe (plutôt plus que moins :p), d'ailleurs je viens de faire le test et avec le type decimal pas de problèmes...
    Le problème c'est les mauvaises habitudes prises par certains collègues... et surtout l'utilisation de cast!

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

Discussions similaires

  1. problème de conversion de dimension dans BUSINESS OBJECT
    Par greatmaster1971 dans le forum Deski
    Réponses: 4
    Dernier message: 28/04/2014, 13h15
  2. - [CAST ou CONVERT] Problème de conversion de date
    Par Boublou dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 06/07/2004, 14h31
  3. Problème de conversion 3DS->.X
    Par JBernn dans le forum DirectX
    Réponses: 5
    Dernier message: 08/04/2004, 19h08
  4. Problème de conversion unicode
    Par djmalo dans le forum C
    Réponses: 5
    Dernier message: 09/03/2004, 11h48
  5. Réponses: 11
    Dernier message: 02/09/2003, 14h20

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