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 :

Valeurs limite des variables float et double


Sujet :

avec Java

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Valeurs limite des variables float et double
    Bonjour à tous,

    Je poste ici pour comprendre les limites de ces 2 variables.
    J'ai bien compris celles des variables d'entiers plus ou moins longs.
    Exemple pour le byte qui vaut 8 bits, donc 256 valeurs possibles, comme on bosse en signé on en met 128 dans les negatifs et 128 dans les positifs.
    Ainsi si je mets le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    byte b = 128; // valeur acceptée.
    byte c = 130; // valeur refusée, on me cast.
    Il en est de même pour tous les autres types d entiers char,int, long...

    Pour ce qui est des floats et des doubles, je galère un peu plus.
    Ils répondent à la norme IEEE 754:
    - le float est de simple précision (32 bits : 1 bit de signe, 8 bits d'exposant (-126 à 127), 23 bits de mantisse),
    - le double est de double précision (64 bits : 1 bit de signe, 11 bits d'exposant (-1022 à 1023), 52 bits de mantisse),

    Alors pourquoi quand je rentre le code:
    Je ne me fais pas caster ? la valeur de la partie entière du nombre excède celle qui devrait être autorisée ? Est-ce que java utilise des bits non nécessaires de la mantisse pour allouer une plus grande valeur à ma partie entière que celle qui devrait être autorisée ?

  2. #2
    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,


    Le stockage des nombres flottants est bien plus complexe, et peut représenter une plage bien plus importante de nombre. Dans ton exemple tu oublies la mantisse.

    Grosso modo pour obtenir le nombre il faut faire ce calcul : mantisse * 2 ^ exposant

    Tu as donc une plage de valeur représentable bien plus grande...
    (voir Float.MAXT_VALUE et Double.MAX_VALUE)


    a++

  3. #3
    Membre expérimenté Avatar de rtg57
    Homme Profil pro
    Autodidacte
    Inscrit en
    Mars 2006
    Messages
    1 340
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Service public

    Informations forums :
    Inscription : Mars 2006
    Messages : 1 340
    Points : 1 576
    Points
    1 576
    Par défaut
    Bonjour, il y a un petit truc sympa sur Wikipédia: http://fr.wikipedia.org/wiki/Virgule_flottante

    Attention, même si ces nombres peuvent encaisser des valeurs monstrueuses, on est parfois déçu par le perte de précision lorsqu'on additionne des montants au centime d'euro.

    Pour revenir plus sur le sujet, avec une mantisse sur 23 bits, on peut déjà atteindre un nombre bien plus conséquent que sur 8 bits. Donc "130" passe largement (sans parler de l'élévation à la puissance de l'exposant )

    En espérant que cela réponde à votre question...
    @ bientôt...

    Salut & @+ sur 3W!

  4. #4
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2008
    Messages
    328
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Mexique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2008
    Messages : 328
    Points : 459
    Points
    459
    Par défaut
    Salut,

    Tout d'abord, voici comment connaître les valeurs mini et maxi d'un type byte:

    VALEUR MINI d'un BYTE.
    >>>> byte mon_byte = Byte.MIN_VALUE;
    La valeur minimale d'un byte est -128

    VALEUR MAXI d'un BYTE.
    >>>> byte mon_byte = Byte.MAX_VALUE;
    La valeur maximale d'un byte est 127

    Donc les 2 valeurs dont tu parles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    byte b = 128;
    byte c = 130;
    dépassent toutes le 2 la valeur maxi d'un byte.
    javac signal les 2 erreurs suivantes:
    ------------.java:nnn: possible loss of precision
    found : int
    required: byte
    byte b = 128; possible loss of precision
    ^
    et
    ------------.java:nnn: possible loss of precision possible loss of precision
    found : int
    required: byte
    byte c = 130; possible loss of precision
    ^

    Ce que l'on peut interpréter come ceci:

    j'ai trouvé une valeur (128 ou 130) qui dépasse la valeur maxi du type byte.

    On ne peut donc pas éxécuter le programme.

    par contre si on a:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    byte b = 127;
             b++;
    System.out.println("b = " + b);
    le compilateur accepte (la syntaxe est correcte)

    On exécute donc et on affiche b = -128

    Il n'y a pas d'exception levée mais alors qu'on pouvait s'attendre à obtenir:
    b = 128 (ce qui n'est pas possible) on obtient la -128.
    avec b+=2 >>>> -127 et en fait c'est imprévisible.
    En principe on ne fait pas de calculs sur un byte. Mais si on en fait il vaut mieux utiliser b = b + 1 qui provoquera une erreur de compilation, plutot que b++, ou b = b + 100, aulieu de b+= 100.

    Par contre avec les autres types d'entiers,par exemple int:
    i = 3456789012; javac signale:
    integer number too large: 3456789012

    FLOAT:

    Ce ne sont ni la partie entière ni la partie décimale qui sont limitées, mais bien toute la valeur du float.

    VALEUR MINI d'un FLOAT.
    >>>> float mon_float = Float.MIN_VALUE;
    La valeur minimale d'un float est 1.4E-45
    soit 1.4 * 10 puissance -45


    VALEUR MAXI d'un FLOAT.
    >>>> float mon_float = Float.MAX_VALUE;
    La valeur maximale d'un float est 3.4028235E38
    soit 3.4028235 * 10 puissance 38

    Attention:

    float f = 3.4028235E38; // err. compile: trouvé double aulieu de float et
    //possible lost..... car il manque le f (ou F).

    float f = 3.4028235E38f; // ok

    float f = 3.4028236E38f; // err floating point number too large

    Cordialement,

    Dan

  5. #5
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2008
    Messages
    328
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Mexique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2008
    Messages : 328
    Points : 459
    Points
    459
    Par défaut
    RE,

    Format général pour VALEUR MINI et VALEUR MAXI pour les entiers et réels :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    le_type mon_type = Type.MIN_VALUE; // exemple: = Double.MIN_VALUE;
    le_type mon_type = Type.MAX_VALUE; // ex. = Long.MAX_VALUE;
     
    //  SAUF pour int:
     
    le_type mon_type = Integer.MIN_VALUE; // et non Int
    le_type mon_type = Integer.MAX_VALUE; // et non Int
    dan

  6. #6
    Membre expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Points : 3 675
    Points
    3 675
    Par défaut
    Citation Envoyé par danimo Voir le message
    Il n'y a pas d'exception levée mais alors qu'on pouvait s'attendre à obtenir:
    b = 128 (ce qui n'est pas possible) on obtient la -128.
    avec b+=2 >>>> -127 et en fait c'est imprévisible.
    c'est tout sauf imprévisible. il suffit d'écrire le résultat attendu en binaire, et de supprimer tout ce qui "dépasse" du byte (c'est d'ailleurs ce que fait la jvm: elle tronque le résultat)

    En principe on ne fait pas de calculs sur un byte.
    bien sûr qu'on en fait... quand on est sur de son coup...

    d'ailleur, petit détail, mais la jvm ne sait pas faire de calcul directement sur des byte ou des short. Il y a promotion vers un int lors de chaque calcul, puis re-conversion du résultat lorsque c'est nécessaire.

    ex: byte b=0; b += 2;

    lorsque l'on fait b+=2, b est promu vers un int, ensuite on ajoute 2 à cet int, puis on re-convertit le résultat vers un byte que l'on stocke dans b.

    voili pour la ptite histoire

    "Le plug gros problème des citations trouvées sur internet, c'est qu'on ne peut jamais garantir leur authenticité"

    Confucius, 448 av. J-C

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 96
    Points : 63
    Points
    63
    Par défaut
    Bonjour,

    désolé de remonter ce sujet, mais malgré toutes vos explications (qui correspondent à peu près à ce que je savais déjà), j'ai une interrogation sur les nombres négatifs.
    En effet, si Float.MIN_VALUE=1.4E-45 et Float.MAX_VALUE=3.4028235E38, un nombre négatif ne devrait pas être accepté non?
    De même qu'en est-il du zéro?
    Peut-on considérer que l'ensemble des float se situe dans l'ensemble ;
    [-Float.MAX_VALUE;-Float.MIN_VALUE] U [Float.MIN_VALUE;Float.MAX_VALUE]?

    Merci d'avance de votre réponse.

    Nico

  8. #8
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Je dirais plutôt [-Float.MAX_VALUE;-Float.MIN_VALUE] U [Float.MIN_VALUE;Float.MAX_VALUE] U {0f ; -0f ; Float.POSITIVE_INFINITY ; Float.NEGATIVE_INFINITY}

    Et éventuellement NaN.

    Mais c'est ça, oui.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  9. #9
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2008
    Messages
    328
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Mexique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juin 2008
    Messages : 328
    Points : 459
    Points
    459
    Par défaut
    Salut,

    Reprenons les valeurs mini et maxi d'un Float:

    MIN_VALUE=1.4E-45
    MAX_VALUE=3.4028235E38

    celà signifie bien que toutes les valeurs possibles sont les valeurs de:
    1.4E-45 à 3.4028235E38.
    Le zéro est bien une de ces valeurs.

    Un nombre négatif, pourvu qu'il soit >= 1.4E-45 sera bien < 3.4028235E38
    Un nombre positif, pourvu qu'il soit <= 3.4028235E38 sera bien > 1.4E-45

    Cordialement,

    Dan

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 96
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par danimo Voir le message
    celà signifie bien que toutes les valeurs possibles sont les valeurs de:
    1.4E-45 à 3.4028235E38.
    Le zéro est bien une de ces valeurs.
    J'ai un peu de mal avec cette explication.
    Pour moi 1.4E-45 = 1.4 * 10 ^ -45 = 1.4 * 1 / (10^45) = 0.00000..............0000qqchose et donc > 0 non?

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 96
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par thelvin Voir le message
    Je dirais plutôt [-Float.MAX_VALUE;-Float.MIN_VALUE] U [Float.MIN_VALUE;Float.MAX_VALUE] U {0f ; -0f ; Float.POSITIVE_INFINITY ; Float.NEGATIVE_INFINITY}

    Et éventuellement NaN.

    Mais c'est ça, oui.
    Merci de ta réponse.
    Cà parait logique mais je n'ai trouvé nulle part une représentation sous forme d'ensemble des float et double.

    Nico

  12. #12
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Ce n'est pas très utile comme représentation, non ?

    D'ailleurs, c'est une notation inexacte : un intervalle représente l'infinité de valeurs situées entre ses deux bornes.
    Alors qu'un float ne peut avoir qu'un nombre fini de valeurs différentes, distribuées irrégulièrement entre ces deux bornes.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 96
    Points : 63
    Points
    63
    Par défaut
    Effectivement, ce n'est pas un notation exacte au sens strict du terme.
    En revanche l'utilité d'une telle représentation dépend de l'utilisation qu'on veut en faire, et en ce qui me concerne et sans rentrer dans les détails, je dois faire du décodage et de l'encodage de flottant respectant IEEE754 à bartir d'un ByteBuffer, et pour vérifier notamment les bornes définition du domaine, j'ai besoin de ces valeurs/intervalles de valeurs.
    En fait c'est plutôt d'une spécification de l'IEEE754 appliquée au langage java dont j'avais besoin, mais tout ce que j'ai trouvé ne répondait pas entièrement à ma question.

    Nico

  14. #14
    Modérateur

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

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    ?

    Peut-être que je n'ai pas compris, mais as-tu lu la JavaDoc de Float.floatToRawIntBits() ?
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  15. #15
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 96
    Points : 63
    Points
    63
    Par défaut
    Oui, je m'en sers d'ailleurs pour encoder mes float dans mon ByteBuffer, mais j'ai plein d'autre contraintes, je dois pouvoir restreindre le nombre de valeurs encodable, pouvoir modifier la "pente" d'encodage décodage, etc... Et pour çà j'avais besoin des bornes MIN et MAX...
    Bref, ta réponse m'a bien aidé...

    Merci

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    les min_value et max_value, comme représentées dans la javadoc sont très claires:

    public static final float MIN_VALUE

    A constant holding the smallest positive nonzero value of type float, 2-149. It is equal to the value returned by Float.intBitsToFloat(0x1).
    c'est donc le plus petit nombre positif non null stockable

    Pour les détails techniques sur les sets de valeurs, etc, tout est détaillé dans le java language specifications

    http://java.sun.com/docs/books/jls/t...ues.html#4.2.3

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    et, danimo, un nombre négatif ne sera jamais >= 1.4E-45

Discussions similaires

  1. [Datatype] limite des types float, double et decimal
    Par yolepro dans le forum XML/XSL et SOAP
    Réponses: 7
    Dernier message: 27/03/2013, 10h41
  2. Déclarer des variables ou un double tableau dynamiquement
    Par calimerojeff dans le forum Langage
    Réponses: 1
    Dernier message: 20/08/2009, 09h21
  3. Stocker des valeurs dans des variables sessions
    Par Jcpan dans le forum Langage
    Réponses: 3
    Dernier message: 31/03/2009, 10h39
  4. modifier une valeur dans des variables
    Par bombjack91 dans le forum VB.NET
    Réponses: 3
    Dernier message: 29/06/2007, 08h14
  5. [VB6] Limitation des variables à 64 Ko
    Par daladim dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 06/06/2006, 21h37

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