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

Langage Java Discussion :

Arrondi commercial problématique


Sujet :

Langage Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 5
    Par défaut Arrondi commercial problématique
    Salut !

    Ma question est simple : comment réaliser un arrondi commercial d'un "double" à deux chiffres après la virgule ? Ou plutôt : pourquoi ma solution ne fonctionne pas correctement ?


    J'avais d'abord pensé à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public static double arrondi(double somme)
      {
        return ((double) Math.round(somme * 100)) / 100;
      }

    Problème :
    Voici une utilisation de cette fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static void main(String args[])
      {
        double total = 1000, interets = 0, interets_arrondis = 0;
        for (int annee = 1; annee <= 10; annee++)
        {
          interets = total * 0.05;
          interets_arrondis = arrondi(interets);
          total += interets_arrondis;
     
          System.out.println("Après " + annee + " année(s) => intérêts : " + interets + " - arrondi : " + interets_arrondis + " - total : " + total);
        }
      }
    et son effet:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Après 1 année(s) => intérêts : 50.0 - arrondi : 50.0 - total : 1050.0
    Après 2 année(s) => intérêts : 52.5 - arrondi : 52.5 - total : 1102.5
    Après 3 année(s) => intérêts : 55.125 - arrondi : 55.13 - total : 1157.63
    Après 4 année(s) => intérêts : 57.88150000000001 - arrondi : 57.88 - total : 1215.5100000000002
    Après 5 année(s) => intérêts : 60.775500000000015 - arrondi : 60.78 - total : 1276.2900000000002
    [...]
    On voit que tout se passe comme prévu jusqu'à la 4ème année, mais après le comportement devient plus étrange. A la quatrième année, l'arrondi est bien fait (57.88150000000001 => 57.88) mais quand on ajoute cet arrondi à une autre somme, on obtient pas le bon résultat : 1157.63 + 57.88 = 1215.5100000000002...

    J'imagine que c'est une histoire de représentation machine des décimaux ou un truc comme ça... Quelqu'un pourrait-il m'expliquer ce qui se passe plus en détail ? Merci d'avance !

  2. #2
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 5
    Par défaut
    Merci. Mais ce n'est pas tellement trouver une autre manière de faire cet arrondi qui m'interesse, c'est surtout COMPRENDRE pourquoi ma solution ne fonctionne pas...

  4. #4
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Cela vient de la façon dont sont représentés les doubles en mémoire. En effet ceux-ci sont ce que l'on appelle des nombres à virgule flottante, c'est-à-dire un nombre dans lequel la position de la virgule n'est pas fixe, et est repérée par une partie de ses bits (appelée l'exposant), le reste des bits permettent de coder le nombre sans virgule (la mantisse).
    Cela entraine une imprecision sur le nombre, c'est d'ailleur pourquoi il ne faut pas utiliser les doubles (ni les floats) pour faire du calcul de précision.
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2006
    Messages : 5
    Par défaut
    Du calcul de précision à deux chiffres après la virgule...

    Un autre exemple d'utilisation de l'arrondi pour voir à quel point c'est bizarre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static void main(String args[])
      {
        System.out.println(0.61 + arrondi(57.88150000000001));
        System.out.println(0.62 + arrondi(57.88150000000001));
        System.out.println(0.63 + arrondi(57.88150000000001));
        System.out.println(0.64 + arrondi(57.88150000000001));
        System.out.println(0.65 + arrondi(57.88150000000001));
        System.out.println(0.66 + arrondi(57.88150000000001));
        System.out.println(0.67 + arrondi(57.88150000000001));
        System.out.println(0.68 + arrondi(57.88150000000001));
        System.out.println(0.69 + arrondi(57.88150000000001));
      }
    donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    58.49
    58.5
    58.510000000000005
    58.52
    58.53
    58.54
    58.550000000000004
    58.56
    58.57

  6. #6
    Expert confirmé
    Avatar de le y@m's
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2005
    Messages
    2 636
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2005
    Messages : 2 636
    Par défaut
    Les 0.000000000000005 et 0.000000000000004 en trop sont le résultat de l'imprécision inhérente aux nombres à virgule flottante.

    Etant donné que tu veux une précision à deux décimales, cela ne posera aucun problème dans tes calculs (dans ton cas l'imprécision est négligeable).

    Le seul problème pour toi vient à l'affichage car si tu affiche un double tel quel et qu'il contient une imprécision, alors celle-ci sera aussi affichée.

    C'est pourquoi tu dois passer par un DecimalFormat pour n'afficher que les deux premières décimales.
    Je ne répondrai à aucune question technique par MP.

    Pensez aux Tutoriels et aux FAQs avant de poster ;) (pour le java il y a aussi JavaSearch), n'oubliez pas non plus la fonction Rechercher.
    Enfin, quand une solution a été trouvée à votre problème
    pensez au tag :resolu:

    Cours Dvp : http://ydisanto.developpez.com
    Blog : http://yann-disanto.blogspot.com/
    Page perso : http://yann-disanto.fr

  7. #7
    Membre expérimenté
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 194
    Par défaut
    Citation Envoyé par cowek
    Du calcul de précision à deux chiffres après la virgule...

    Un autre exemple d'utilisation de l'arrondi pour voir à quel point c'est bizarre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static void main(String args[])
      {
        System.out.println(0.61 + arrondi(57.88150000000001));
        System.out.println(0.62 + arrondi(57.88150000000001));
        System.out.println(0.63 + arrondi(57.88150000000001));
        System.out.println(0.64 + arrondi(57.88150000000001));
        System.out.println(0.65 + arrondi(57.88150000000001));
        System.out.println(0.66 + arrondi(57.88150000000001));
        System.out.println(0.67 + arrondi(57.88150000000001));
        System.out.println(0.68 + arrondi(57.88150000000001));
        System.out.println(0.69 + arrondi(57.88150000000001));
      }
    donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    58.49
    58.5
    58.510000000000005
    58.52
    58.53
    58.54
    58.550000000000004
    58.56
    58.57
    Il y a encore un truc qui va te défriser encore un peu plus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    System.out.println(.63+57.88);
    affiche :
    58.510000000000005
    La solution à ton problème, oui il y a en a une :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    public static double arrondi(double d) {
         return Math.rint(d);
    }
    [EDIT] J'ai revérifié, Math.rint(d) ne fait pas ce que je pensais, la méthode se contente de faire (long)d

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

Discussions similaires

  1. [Math]Problème troncage ou arrondi sur des valeurs
    Par Carrel dans le forum Général Java
    Réponses: 6
    Dernier message: 07/10/2009, 16h11
  2. [BigDecimal] les arrondis...
    Par LoulouFifi dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 13/01/2004, 19h37
  3. création d'un bouton de forme arrondie
    Par THIERRY L. dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/12/2003, 15h04
  4. Sauvegarde problématique sous excel par OLE
    Par ulysse66x dans le forum API, COM et SDKs
    Réponses: 2
    Dernier message: 16/04/2003, 22h23
  5. [VB6] Racine carrée + arrondi
    Par Krys29 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/10/2002, 14h19

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