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. #21
    Membre émérite

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    code édité :
    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
     
     
    package testsestsest;
     
    import java.lang.Float;
     
    public class Test_log4j {
     
        public static void main(String[] args) {
     
     
            int n1=2;
            int n2=0;
                if (calcul(n1,n2)!= 2.1474836E7){
                System.out.println("Résultat de (" + n1 + "+" + n2 + ")/" + n2 + " : " + calcul(n1,n2));
                }
     
        }
     
        public static float calcul(float nb1, float nb2) {
            float nb3 = 0;
            System.out.println("Calcul lancé ...");
     
            nb3 = (nb1 + nb2) / nb2;
            Float nb3Float = new Float(nb3);
            if (nb3Float.isInfinite()) {
                System.out.println("Erreur fatale !!");
            } 
                // méthode pour arrondir à 2 chiffres après la virgule
                nb3 *= 100;
                nb3 = (int) (nb3 + .5);
                nb3 /= 100;
            return nb3;
        }
    }

  2. #22
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Pas la peine de créer un objet Float pour vérifier si c'est infini : tu peux directement utiliser la méthode static :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (Float.isInfinite(nb3))



    Mais en castant vers des int tu risques toujours d'avoir un résultat tronqué pour des valeurs float supérieur à Integer.MAX_VALUE...

    Juste pour l'anecdote, c'est un bug de ce style qui a fait dévier le tout premier vol de la fusée Ariane 5... ce qui a obligé les techniciens à la faire exploser !

    a++

  3. #23
    Membre émérite
    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
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    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...
    Oui on a trouvé ça avec nayah aussi.

    Citation Envoyé par adiGuba Voir le message
    Si cet arrondi est uniquement utile pour l'affichage, tu devrais plutôt utiliser DecimalFormat (c'est d'ailleurs indiqué dans la FAQ)
    J'ai besoin de réutiliser ce nombre avec uniquement 2 chiffres après la virgule justement, donc je ne peux pas utiliser le DecimalFormat .

    Le code que tu as mis, je n'arrive pas à l'appliquer... Il me renvoie toujours infinity, autrement dit, je suis obligée de passer un test de toutes façons, je peux oublier mon traitement d'exception .

  4. #24
    Membre émérite
    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
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Pas la peine de créer un objet Float pour vérifier si c'est infini : tu peux directement utiliser la méthode static :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (Float.isInfinite(nb3))
    Mais en castant vers des int tu risques toujours d'avoir un résultat tronqué pour des valeurs float supérieur à Integer.MAX_VALUE...

    Juste pour l'anecdote, c'est un bug de ce style qui a fait dévier le tout premier vol de la fusée Ariane 5... ce qui a obligé les techniciens à la faire exploser !

    a++
    C'est marrant ça, je vais peut-être bientôt travailler pour une société dans l'aéronautique , mais je ferai du BO, donc je ferai pas crasher les navions ...

  5. #25
    Membre émérite

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    voila j'ai modifié le code que j'avais posté ca devrai marcher nickel maintenant...
    en fin j'espere

  6. #26
    Membre émérite
    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
    Par défaut
    Il m'affiche bien "Erreur fatale", mais il m'affiche quand même 2.1474....

    Et le else ne passe pas, ça serait trop beau...

  7. #27
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ayana Voir le message
    Le code que tu as mis, je n'arrive pas à l'appliquer... Il me renvoie toujours infinity
    Oui c'est normal... L'infini ne peut pas être arrondi !

    Citation Envoyé par Ayana Voir le message
    Il m'affiche bien "Erreur fatale", mais il m'affiche quand même 2.1474....

    Et le else ne passe pas, ça serait trop beau...
    Tu n'as pas de else dans ton code !

    Peut-être que tu devrais remonter une exception ?

    a++

  8. #28
    Membre émérite

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    Citation Envoyé par Ayana Voir le message
    Il m'affiche bien "Erreur fatale", mais il m'affiche quand même 2.1474....

    Et le else ne passe pas, ça serait trop beau...
    il n'y a pas de else....

  9. #29
    Membre émérite
    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
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Tu n'as pas de else dans ton code !

    Peut-être que tu devrais remonter une exception ?

    a++
    Si tu regardes son code, on ne peut pas mettre un if/else, puisqu'il faut retourner un double ...

    Je vais réessayer avec mon traitement d'exception que j'avais déjà fait avant (cf. post 1e page).

  10. #30
    Membre émérite

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    Citation Envoyé par Ayana Voir le message
    Si tu regardes son code, on ne peut pas mettre un if/else, puisqu'il faut retourner un double ...
    heu je comprends pas ce que tu dis mon if ne me sert qu'a tester un booleen mais en aucun cas il n'intervient dans le retour du float...

    tu pourrai t'expliquer svp ?

    PS : Je viens de tester le code il fonctionne ... peut etre ais je mal compris ce qu'il doit réaliser peut tu me l'expliquer ?

  11. #31
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ayana Voir le message
    Si tu regardes son code, on ne peut pas mettre un if/else, puisqu'il faut retourner un double ...
    C'est pour cela que j'ai dit qu'il sera préférable dans ce cas là de remonter une exception...

    Citation Envoyé par nayah Voir le message
    heu je comprends pas ce que tu dis mon if ne me sert qu'a tester un booleen mais en aucun cas il n'intervient dans le retour du float...

    tu pourrai t'expliquer svp ?
    Le if() se contente d'afficher une valeur. La suite de la méthode (et donc sa valeur de retour) n'est pas impacté

    a++

  12. #32
    Membre émérite
    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
    Par défaut
    Moi ce que je veux c'est :
    si nb3.isInfinite==true, alors exception/message
    sinon calcul

    Dans ton code, le renvoi du calcul se fait toujours, alors que je n'en veux pas.


    Mais j'ai trouvé la solution, j'ai remis mes exceptions en fin de compte .
    Je la colle pour ceux que ça intéresse.

    MathException.java
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public class MathException extends Exception {
     
      public MathException(){
     
      }
    }
    Test_log4j.java
    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
    36
    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");
     
      	  	float n1=2;
      	  	float n2=0;
     
      	  	try{
      	  	    logger.info("Résultat de (" + n1 + "+" + n2 + ")/" + n2 + " : " + calcul(n1,n2));
      	  	}catch (MathException e){
                        // traitement des erreurs mathématiques (division par 0 ...)
      	  	    logger.fatal("Erreur arithmétique !!");
      	  	}
      	}
     
      	public static float calcul(float nb1, float nb2) throws MathException{
      	  	logger.info("Calcul lancé ...");
      	  	float nb3=(nb1+nb2)/nb2;
      	  	if (Float.isInfinite(nb3) || Float.isNaN(nb3)) throw new MathException();
    	  	 // méthode pour arrondir à 2 chiffres après la virgule
    	        nb3 *= 100;
    	        nb3 = (int) (nb3 + .5);
    	        nb3 /= 100;
    	        return nb3;
      	}
    }

    Merci à vous 2 en tout cas .
    nayah, tu y as passé ton aprem .

  13. #33
    Membre émérite
    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
    Par défaut
    Oups, j'ai fais avec n1=0 et n2=0 .... pas d'exception déclenchée


    Edit : tout ça pour un problème de format ... pas au point le Java là-dessus !

  14. #34
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Si tu remontes une exception le else devient inutile

    Citation Envoyé par Ayana Voir le message
    Oups, j'ai fais avec n1=0 et n2=0 .... pas d'exception déclenchée
    Normal car 0.0+0.0/0.0 == 0.0 et non pas l'infini...

    Que devrait faire ton calcul exactement ?

    Et attention car si ton résultat est plus grand que 2147483647 il sera complètement faux !

    a++

    [edit aussi]
    Citation Envoyé par Ayana Voir le message
    Edit : tout ça pour un problème de format ... pas au point le Java là-dessus !
    Pas compris

  15. #35
    Membre émérite
    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
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Si tu remontes une exception le else devient inutile
    je n'en ai pas mise

    Citation Envoyé par adiGuba Voir le message
    Et attention car si ton résultat est plus grand que 2147483647 il sera complètement faux !
    ça passera en test, je mettrai des valeurs limites
    mais j'ai pas tout fini

    Citation Envoyé par adiGuba Voir le message
    Pas compris
    Ben si tu regardes le premier post, j'ai fait ce topic juste pour avoir un nombre avec 2 chiffres après la virgule ... et j'en suis rendue à faire des float, des calculs de base pour avoir ces décimales et des exceptions .


    J'ai trouvé l'erreur, il manquait un test, j'ai corrigé dans mon code.
    0/0 donne NaN (Not-a-Number) !!

    Mais je vais devoir mettre des arrondis à l'affichage aussi, parce que pour lui (3-2)/2=0.49

  16. #36
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Ayana Voir le message
    je n'en ai pas mise
    Ben pourtant il y a bien un else dans le dernier code que tu donnes...

    Citation Envoyé par Ayana Voir le message
    Mais je vais devoir mettre des arrondis à l'affichage aussi, parce que pour lui (3-2)/2=0.49
    Les calculs sur les floats ne sont pas forcément précis... Utilises des doubles ou des BigDecimal si tu veux une précisions plus poussé...

    a++

    PS : et essayes de mettres les calcul précis qu'on sache ce que tu utilises, car (3-2)/2 c'est des int et donc cela fait 0...

  17. #37
    Membre émérite
    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
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Ben pourtant il y a bien un else dans le dernier code que tu donnes...
    Oui j'ai oublié de l'enlever ici, je le fais de suite

    Citation Envoyé par adiGuba Voir le message
    Les calculs sur les floats ne sont pas forcément précis... Utilises des doubles ou des BigDecimal si tu veux une précisions plus poussé...
    C'est noté .

    Citation Envoyé par adiGuba Voir le message
    PS : et essayes de mettres les calcul précis qu'on sache ce que tu utilises, car (3-2)/2 c'est des int et donc cela fait 0...
    non en fait j'ai tout mis en float .... (cf. code)


    Bon allez, sur ce, je vous souhaite bon week-end et bonnes rêveries de Java.

    Et encore merci

  18. #38
    Membre émérite
    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
    Par défaut
    Bon, j'ai refait ma classe entièrement, j'étais inspirée ce matin .


    Test_log4j_2.java
    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
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    /*
     * Created on 22 oct. 2007
     */
    package test_logging_2;
     
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.Reader;
    import java.util.Locale;
     
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
     
    import test_logging.MathException;
     
    /**
     * @author Ayana
     */
     
    public class Test_log4j_2 {
     
      private static final Logger logger = Logger.getLogger(Test_log4j_2.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) throws IOException, NumberFormatException {
     
        // on configure via le fichier "log4j.properties" placé avec le fichier ".classpath"
    	PropertyConfigurator.configure("log4j.properties");
     
      	try{
     
      	  	    logger.info("Le résultat est : " + getInt() );
      	  	}catch (MathException e){
      	  	    // traitement des erreurs arithmétiques (division par 0 ...)
      	  	    logger.fatal("Erreur arithmétique !!");
      	  	}  	
    		catch (NumberFormatException ioe){
    		  	// traitement des erreurs de format pour les nombres (entrer des entiers !)
    		  	logger.fatal("Il faut des nombres entiers !");
    		}
     
      }
     
    	// méthode pour que l'utilisateur rentre lui-même les valeurs
    	public static float getInt() throws IOException, MathException{
    		try{
    			Reader reader1 = new InputStreamReader(System.in);
    			BufferedReader keyboard1 = new BufferedReader(reader1);
     
    			logger.info("Vous allez réaliser l'opération : (n1+n2)/n2.");
    			System.out.print("Entrez le 1er nombre entier : ");
    			String nombre1 = keyboard1.readLine();
    			System.out.print("Entrez le 2e nombre entier : ");
    			String nombre2 = keyboard1.readLine();
    			logger.info("Vous avez choisi l'opération : (" + nombre1 + "+" + nombre2 + ")/" + nombre2 + ".");
    			// conversion d'un String vers un float en passant par un Integer pour lever une exception à la saisie
    			Integer nbre1=new Integer(nombre1);
    			float nb1=nbre1.floatValue();
    			Integer nbre2=new Integer(nombre2);
    			float nb2=nbre2.floatValue();
    			float nb3=calcul(nb1,nb2);
    			return nb3;
    		}
    		catch (IOException ioe){
    			throw ioe;
    		}
     
     
    	}
     
      	public static float calcul(float nb1, float nb2) throws MathException {
    	  	logger.info("Calcul lancé ...");
    	  	float nb3=(nb1+nb2)/nb2;
    	  	if (Float.isInfinite(nb3) || Float.isNaN(nb3)) throw new MathException();
    	  	// méthode pour arrondir à 2 chiffres après la virgule
    	    nb3 *= 100;
    	    nb3 = (int) (nb3+.5);
    	    nb3 /= 100;
    	    return nb3;
    	}
     
     
    }
    A l'affichage :
    22/10/2007 10:20:05. INFO : Vous allez réaliser l'opération : (n1+n2)/n2.
    Entrez le 1er nombre entier : 5
    Entrez le 2e nombre entier : 3
    22/10/2007 10:20:09. INFO : Vous avez choisi l'opération : (5+3)/3.
    22/10/2007 10:20:09. INFO : Calcul lancé ...
    22/10/2007 10:20:09. INFO : Le résultat est : 2.67
    Voilà .

  19. #39
    Membre émérite

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 510
    Par défaut
    Citation Envoyé par Ayana Voir le message
    nayah, tu y as passé ton aprem .
    de rien c'est toujours un plaisir

    désolé pour le temps de réponse jepeuxme connecter qu'une semaine sur deux

    content que tu es résolu ton probleme et a +

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. Pb d'arrondie de type double
    Par la debutante dans le forum C#
    Réponses: 10
    Dernier message: 19/09/2007, 17h47
  2. float, double et arrondi
    Par simla dans le forum Langage
    Réponses: 2
    Dernier message: 25/08/2007, 16h22
  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, 11h17
  4. arrondi avec type double
    Par la drogue c'est mal dans le forum MFC
    Réponses: 6
    Dernier message: 08/04/2005, 18h51

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