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

avec Java Discussion :

BigDecimal et arrondi


Sujet :

avec Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut BigDecimal et arrondi
    Bonjour,

    J'ai un problème simple mais pour lequel je ne trouve pas de solution "simple" :
    Je cherche à faire un arrondi de 3 chiffres après la virgule.

    Je cherche à éviter la manipulation des doubles et j'utilise donc le type BigDecimal.
    De ce que je comprend avec un MathContext ou en faisant un setScale() on peut spécifier une précision.
    Le problème est que cette précision semble être le nombre de chiffres significatifs et non pas le nombre de chiffres après la virgule. Je m'explique :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    		MathContext MC3 = new MathContext(3, RoundingMode.HALF_UP);
    		BigDecimal bd1 = new BigDecimal("1");
    		BigDecimal bd30 = new BigDecimal("30");
    		BigDecimal bdres = bd1.divide(bd30, MC3);
    		System.out.println(bdres.toString()); //==> 0.0333
     
    		BigDecimal bd2 = new BigDecimal("1");
    		BigDecimal bd3 = new BigDecimal("3");
    		BigDecimal bdres2 = bd2.divide(bd3, MC3);
    		System.out.println(bdres2.toString()); //==> 0.333
    Comment faut-il faire pour avoir 0.033 sur la première division ? Y a-t-il une méthode qui permette de limiter le nombre de décimales ?
    (De préférence sans passer par (x*1000 + 0.5)/1000 ou par une chaîne de caractères)

    (J'ai cherché dans le forum mais je n'ai rien de trouvé de similaire)

    Merci d'avance pour votre aide

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

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

    Informations forums :
    Inscription : Août 2006
    Messages : 4 093
    Par défaut
    Pour avoir 0.033 il faut que mettes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MathContext MC3 = new MathContext(2, RoundingMode.HALF_UP);
    au lieu de

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MathContext MC3 = new MathContext(3, RoundingMode.HALF_UP);
    mais j'avoue ne pas être sur d'avoir bien compris ta question.
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Pour avoir une précision finale bien déterminée, il faut appliquer cela après le calcul, via un appel à setScale il me semble.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 576
    Par défaut
    Se pose donc la question de quelle précision faut-il donner au premier calcul.
    Je vois bien comment bricoler en le faisant d'abord avec une précision de 1, regardant le scale obtenu, déduisant la précision nécessaire pour 3 chiffres après la virgule, et refaisant le calcul. Mais je me demande s'il n'y a pas plus droit au but.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut
    Bonjour,

    Merci à vous de vous être penchés sur mon problème.
    Pour résumer :

    @Wax78 : effectivement mais mon code était là pour illustrer mon problème. J'aurai aimé avoir la méthode qui fonctionne en ne connaissant pas à l'avance les 2 nombres.

    @tchize : Apparemment ça ne fonctionne pas (cf code ci dessous) (en fait je crois que je n'ai pas bien compris comment me servir de setScale)

    @thelvin : le "bricolage" fonctionne. Je trouve un peu dommage de devoir passer par cette étape supplémentaire mais je pense que je vais opter pour cette solution.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    		MathContext MC3 = new MathContext(3, RoundingMode.HALF_UP);
    		BigDecimal bd1 = new BigDecimal("1");
    		BigDecimal bd30 = new BigDecimal("30");
    		BigDecimal bdres = bd1.divide(bd30, MC3);
    		System.out.println(bdres.toString()); //==> 0.0333
    		bdres.setScale(3, RoundingMode.HALF_UP);
    		System.out.println(bdres.toString()); //==> 0.0333
    		System.out.println(bdres.scale()); //==> 4
     
    		BigDecimal bd2 = new BigDecimal("1");
    		BigDecimal bd3 = new BigDecimal("3");
    		BigDecimal bdres2 = bd2.divide(bd3, MC3);
    		System.out.println(bdres2.toString()); //==> 0.333
    		System.out.println(bdres2.scale()); //==> 3
    Je laisse le sujet ouvert pour voir si quelqu'un a une solution qui va un peu plus "droit au but".

    Merci encore

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut
    Pourquoi faire simple quand on peut faire compliqué....
    Mes excuses, je n'avais pas bien cherché avant de poster

    J'étais parti sur l'utilisation d'un MathContext alors que ça fonctionne mieux sans (dans mon cas)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		BigDecimal bd1 = new BigDecimal("1");
    		BigDecimal bd30 = new BigDecimal("30");
    		BigDecimal bdres = bd1.divide(bd30, 3, RoundingMode.HALF_UP);
    		System.out.println(bdres.toString());//==>0.033
    Merci encore

  7. #7
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 576
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 576
    Par défaut
    Effectivement... -_-°.

    BigDecimal est une de ces classes que je n'arrive pas à étudier correctement, alors que pour ce que j'en vois, elle est pourtant très bien faite.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  8. #8
    Expert éminent
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    pour info, setScale, c'est comme toutes les autres méthode de modification de BigDecimal: ca te retourne un nouveau BigDecimal. BigDecimal est invariant, aucune méthode ne change sa valeur ou sa précision, toutes les méthodes construisent une nouvelle valeur.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut
    Effectivement, (j'ai vraiment fait n'importe quoi ... )
    Je n'avais pas fait attention à la javadoc et le setScale fonctionne bien aussi !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    		BigDecimal bd1 = new BigDecimal("1");
    		BigDecimal bd30 = new BigDecimal("30");
    		//BigDecimal bdres = bd1.divide(bd30, 3, RoundingMode.HALF_UP);
    		BigDecimal bdres = bd1.divide(bd30, 12, RoundingMode.HALF_UP);
    		System.out.println(bdres.toString());	//==> 0.033333333333
    		BigDecimal bdres2 = bdres.setScale(3, RoundingMode.HALF_UP);
    		System.out.println(bdres2.toString()); //==> 0.033

+ 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, 15h11
  2. [BigDecimal] Problème d'arrondi
    Par Boosters dans le forum Langage
    Réponses: 4
    Dernier message: 29/08/2006, 09h31
  3. [BigDecimal] les arrondis...
    Par LoulouFifi dans le forum API standards et tierces
    Réponses: 3
    Dernier message: 13/01/2004, 18h37
  4. création d'un bouton de forme arrondie
    Par THIERRY L. dans le forum C++Builder
    Réponses: 2
    Dernier message: 15/12/2003, 14h04
  5. [VB6] Racine carrée + arrondi
    Par Krys29 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/10/2002, 13h19

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