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 :

pb - résultat de type double/float arrondi


Sujet :

Langage Java

  1. #1
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut pb - résultat de type double/float arrondi
    Bonjour à tous,

    J'ai un petit soucis concernant un type de données.

    Je fais un petit calcul tout bête, à savoir (2+3)*3. Le résultat attendu est 1.66666....
    Or, le résultat que j'ai est 1.0

    J'ai beau avoir lu la FAQ et certains topics, les problèmes rencontrés sont plutôt inverses au mien, c'est-à-dire que les développeurs cherchent à restreindre le nombre de chiffres après la virgule.
    Moi j'aimerais en avoir 2 après la virgule, mais je n'arrive même pas à en avoir un, il arrondit systématiquement à l'inférieur !!

    Voici mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public static double calcul(int nb1, int nb2){
      	  	return (nb1+nb2)/nb2;
      	}
    Que je mette en double ou en float, j'ai exactement le même résultat.

    Je suis sur Eclipse 3.0.1.

    Faut-il changer un paramètre sur Eclipse ou y-a-t-il une fonction pour résoudre se problème, autre que BigDecimal ???

    Merci d'avance pour votre aide .

  2. #2
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    déclare tes nombres nb1 et nb2 comme des float et ton résultat est également un float :

    j'ai exécuté ca rapidement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    package testsestsest;
    public class Testest {
        public static void main(String[] args) {
            float nb3, nb1=2, nb2=3;
            nb3= (nb1+nb2)/nb2;
            System.out.println(+nb3);
        }
    }
    et ca me donne 1.6666666 en sortie

  3. #3
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Oui, ça me donne les chiffres après la virgule, merci .
    Et si je mets en double, j'ai 1.6666666666666667

    Mais si je ne veux que 2 chiffres après la virgule ?

    Edit : J'ai fait ça, d'après la FAQ, mais il n'y a pas d'autres solutions ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     public static float calcul(float nb1, float nb2){
      	  	logger.info("Calcul lancé ...");
      	  	float nb3=(nb1+nb2)/nb2;
      	  	nb3*=100;
      	  	nb3 = (int)(nb3+.5);
      	  	nb3/=100;
      	  	return nb3;
      	}

  4. #4
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    Citation Envoyé par Ayana Voir le message

    J'ai beau avoir lu la FAQ et certains topics, les problèmes rencontrés sont plutôt inverses au mien, c'est-à-dire que les développeurs cherchent à restreindre le nombre de chiffres après la virgule.
    je ne fais que te citer ca veut dire que tu as déja trouvé la solution...
    plus sérieusement j'ai déja vu la solution dans un topic mais je sais plus comment faire

    edit: si il y a d'autre solutions attend je cherche...

  5. #5
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Merci à toi en tout cas, je n'avais pas penser à déclarer les paramètres du même type que la sortie.

    Par contre dans mon main() j'ai gardé mes déclarations en int, ça me permet de faire mon traitement d'exception, vu que je ne veux que des entiers en entrée .

  6. #6
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    J'avais mis le "résolu" mais je l'ai enlevé une fois que j'ai fini les tests .

    La partie qui a été vue ci-dessus fonctionne, mais dans l'ensemble de mon programme, ça me pose un GROS problème pour lever une exception.

    Voici mon piti programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class Test_log4j {
     
      	private static final Logger logger = Logger.getLogger(Test_log4j.class);
      	// équivalent --> static Category cat = Category.getInstance(Test_log4j.class.getName());
      	// on le met en statique afin d'économiser de la mémoire
     
      	// choix de la langue --> Locale.getDefault() <=> Locale.FRANCE
      	Locale locale = Locale.getDefault();
     
      	public static void main(String[] args) {
     
      	  	// on configure via le fichier "log4j.properties" placé avec le fichier ".classpath"
      	  	PropertyConfigurator.configure("log4j.properties");
     
      	  	int n1=2;
      	  	int n2=0;
     
      	  	try{
       	  	   logger.info("Résultat de (" + n1 + "+" + n2 + ")/" + n2 + " : " + calcul(n1,n2));
      	  	}catch (ArithmeticException e){
      	  	   // traitement des erreurs mathématiques (division par 0 ...)
      	  	   logger.fatal("Erreur fatale !!");
      	  	}
      	}
     
      	public static float calcul(float nb1, float nb2){
      	  	logger.info("Calcul lancé ...");
      	  	float nb3=(nb1+nb2)/nb2;
      	  	// méthode pour arrondir à 2 chiffres après la virgule
      	  	nb3*=100;
      	  	nb3 = (int)(nb3+.5);
      	  	nb3/=100;
      	  	return nb3;
      	}
    }
    Avant de modifier ma méthode calcul, je pouvais lever une exception pour les divisions par 0.
    Maintenant que j'ai mis en float, ça n'est plus le cas .
    En gros, 0 en float n'est pas un bô 0 comme je les aime ...
    Et en résultat il me met : 2.1474836E7
    Si j'enlève la partie qui me permet d'arrondir, le résultat est éloquent : Infinity

    Que faire ??

  7. #7
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    question pourquoi tu fais ca :
    sinon pour ta division par 0 tu n'a qu'a faire un test sur nb2 tu n'a pas besoin de lever une exception...

  8. #8
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Heu, je fais bêtement ce qu'il y a dans la FAQ



    si je fais (2+3)*3, ça me donne n3=1.66666666666....7
    n4=n3*100=166.66666...7
    n5=entier(n4+0.5)=entier(167.16666)=167
    resultat=n5/100=1.67

    Et j'ai mon résultat arrondi, bizarrement mais ça marche

  9. #9
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Citation Envoyé par nayah Voir le message
    question pourquoi tu fais ca :
    sinon pour ta division par 0 tu n'a qu'a faire un test sur nb2 tu n'a pas besoin de lever une exception...
    C'était juste pour tester ma journalisation (qui marche d'ailleurs ) couplée à une exception.
    Mais j'aurais bien aimé trouver une "bonne" solution à mon piti problème de format quand même .

  10. #10
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    ok je cherche pour etre franc j'essai de trouver comment lui faire comprendre que 0.0 =0 lol

  11. #11
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    J'ai essayé en mettant les paramètres en int et en les convertissant après, mais ça marche pô

  12. #12
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    j'ai essayé pas mal de trucs mais j'avoue que je commence a secher entre le "infinity et le 2.1474836E7 je comprends pas... j'ai meme changer la srtucture du programme et je tombe toujours sur les meme résultats...
    je sais pas si je vais arriver a t'aider

  13. #13
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Le infinity je le comprends, une division "tend" vers l'infini (cours de lycée, beurk ).
    Mais le 2.1474836E7, je trouvais que ça ressemblait à une exponentielle .

    Edit : Eh non, l'exp(1)=2.71

  14. #14
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    ok je sais ce qui se passe

    on risque pas de retourner une ecxeption on réalise le calcul sur un float... (faut vraiment que je soit a***ti pour pas l'avoir remarqué)

    je crois pas qu'il existe une exception qu'on puisse soulever mais je crois qu'il y a quelque chose a faire avec la classe math... on peut vérifier si le résultat est finie ou infini (avant l'arrondi bien sur )

    PS: le 0 en float c'est un nombre qui tend vers 0 d'ou le infinity

  15. #15
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Dites-moi que je suis bête .....

    2.1474836E7 => types "long int" et "int" (4 octets), valeurs de -2.147.483.648 à 2.147.483.647


    Vive l'informatique que je ne faisais pas au lycée ...

  16. #16
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    mais non tu n'est pas bete j'y avais pas penser non plus
    heu ....mauvaise exemple

    edit jete un oeil a la classe math pour ce que j'ai dis au post precedent

  17. #17
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    C'est ce que j'ai fait, j'ai regardé, rint, floor, round ... les tan/cos/sin on s'en fout ... random, degrés, radians aussi .... log, sqrt, exp, pow on s'en fout aussi ...

    J'ai testé avec rint, round et floor, mais marche pas ... ça me met 2.0

  18. #18
    Membre éclairé

    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Points : 803
    Points
    803
    Par défaut
    il y a un truc qui s'appelle isinfinite mais je sais pas ou je cherche

    edit : import java.lang.Float;

  19. #19
    Membre éprouvé
    Avatar de Ayana
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    901
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 901
    Points : 1 180
    Points
    1 180
    Par défaut
    Dans la classe Double()

    Je teste ....

  20. #20
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Citation Envoyé par Ayana Voir le message
    Le infinity je le comprends, une division "tend" vers l'infini (cours de lycée, beurk ).
    En effet les divisions par zéro sur des réels renvoi l'infini, qui est représenté par une valeur incorrect (Float.POSITIVE_INFINITY dans ce cas précis).

    Citation Envoyé par Ayana Voir le message
    Mais le 2.1474836E7, je trouvais que ça ressemblait à une exponentielle .
    2.1474836E7 == 2147483647 == Integer.MAX_VALUE

    Rappel : Les casts d'un type à l'autre sont dangereux. Si dans le cas des objets ils peuvent générer des exceptions, dans le cas des types numériques ils peuvent provoquer des pertes d'informations plutôt dangereuse...

    Ainsi la valeur float est tronqué pour tenir dans un int, et l'infini se transforme en la valeur maximum possible pour un int >> Integer.MAX_VALUE

    Ce qui fausse tout le calcul...



    Si cet arrondi est uniquement utile pour l'affichage, tu devrais plutôt utiliser DecimalFormat (c'est d'ailleurs indiqué dans la FAQ)



    Mais si tu tiens vraiment à arrondir la valeur et pour éviter ce problème il suffit de ne manipuler que des float (ou des double) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    	/**
             * Arrondi d'un double avec n éléments après la virgule
             */
    	public static float floor(float value, int n) {
    		return (float)floor((double)value, n);
    	}
     
    	/**
             * Arrondi d'un double avec n éléments après la virgule
             */
    	public static double floor(double value, int n) {
    		double multi = Math.pow(10.0, n);
    		// Math.floor() supprime la partie décimale
    		return Math.floor(value*multi)/multi;
    	}
    Tu peux avoir un problème si tu atteint la limite supérieur à cause de la multiplication mais cette limite est vraiment loin (1e308)

    a++

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Pb d'arrondie de type double
    Par la debutante dans le forum C#
    Réponses: 10
    Dernier message: 19/09/2007, 16h47
  2. float, double et arrondi
    Par simla dans le forum Langage
    Réponses: 2
    Dernier message: 25/08/2007, 15h22
  3. [C] Récupérer un résultat de fonction de type double
    Par EnigmuS dans le forum x86 32-bits / 64-bits
    Réponses: 10
    Dernier message: 23/04/2007, 10h17
  4. arrondi avec type double
    Par la drogue c'est mal dans le forum MFC
    Réponses: 6
    Dernier message: 08/04/2005, 17h51

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