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 :

Précision du type float


Sujet :

Langage Java

  1. #1
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 14
    Points
    14
    Par défaut Précision du type float
    Bonjour,

    j'essaie de comprendre un problème concernant le type float, j'ai le code suivant :

    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
     
    String s = "738290.76" ;
    Float f = Float.valueOf(s) ;
    Double d = Double.parseDouble(s);
     
    System.out.println("s="+s+" , f="+f+" , d="+d); 
     
    -->s=738290.76 , f=738290.75 , d=738290.76
     
     
    String s2 = "160944.36";
    Float f2 = Float.valueOf(s2) ;
    Double d2 = Double.parseDouble(s2);
     
    System.out.println("s="+s2+" , f="+f2+" , d="+d2); 
     
    --> s=160944.36 , f=160944.36 , d=160944.36


    mon problème concerne la perte de la précision sur le type float le nombre 738290.76 se transforme en 738290.75 avec une conversion de type, mais le type double préserve sa précision.

    ce n'est pas forcément un problème de conversion car quand je lis un champ dans un fichier délimité déclaré en float, j'ai aussi des fois cette perte (c'est aléatoire). c'est peut être lié à l'encodage du fichier (si je déclare un fichier comme UTF-8 alors que c'est de l'ASCII peut être que ce n'est pas encodés de la même manière vu le nombre d'octets utilisés .....) ?

    pouvez vous m'orienter vers les sujets qui traite ceci car quand je cherche une réponse à ce problème je trouve des réponses qui parlent de comment convertir en float, ou comment arrondir un float.

    je suis également tombé sur un article qui dit que les ordinateurs ne savent pas traiter les nombres réels et que le résultat des float (a*b) * c peut être différent de a*(b*c) :

    http://www.lactamme.polytechnique.fr...rs.01.Fra.html


    voilà donc dans quelle mesure puis je garantir un résultat fiable et fidèle à la source ? le type double a t il aussi cette limite ? sachant que je travaille sur un projet comptable et je ne peux pas me permettre la perte du moindre centime, merci.

  2. #2
    Membre régulier
    Homme Profil pro
    Développeur java, .Net
    Inscrit en
    Janvier 2011
    Messages
    55
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Développeur java, .Net

    Informations forums :
    Inscription : Janvier 2011
    Messages : 55
    Points : 71
    Points
    71
    Par défaut
    Il faut mieux utiliser la classe BigDecimal. C'est plus précis que les double.

  3. #3
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 14
    Points
    14
    Par défaut
    merci,

    d'accord, j'utiliserais plutôt ce type de données,

    mais il y a t il une explication à ce phénomène et les raisons possibles, j'aimerais bien comprendre ce qui s'est passé, et je dois aussi expliquer la raison de cette anomalie à mes collègues de la recette .

    merci,

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


    Comme dans la majorité des langages, les float/doubles utilisent une représentation à virgule flottante.
    Ces nombres sont représentés par un mantisse associé à un exposant.

    Ainsi le nombre 738290.76 est représenté sous la forme 73829076 * 102, avec un mantisse qui vaut 73829076 et un exposant qui vaut 2

    Le problème c'est que la taille mémoire de ces types est fixe, et qu'il est donc impossible de représenter toutes les valeurs possibles... alors qu'il y a une infinité de valeurs possibles !!!
    Ils ne peuvent donc représenter que des approximations de ces valeurs, avec une précision variable.

    Généralement on compte environ 7 chiffres significatifs pour les floats, et 16 pour les doubles.
    Tu auras forcément des imprécisions dès que tu approches ou dépasses ces valeurs...


    a++

  5. #5
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 14
    Points
    14
    Par défaut
    Merci pour cette réponse,

    si j'ai que 2 décimaux à partir de 100.000 euros je commence à avoir des incertitudes pour des float ?

    merci,

  6. #6
    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
    Hello,

    tu commences à avoir des incertitudes dès que tu as du décimal dans ton nombre.

    Par exemple, il n'est pas possible de représenter exactement le nombre 0,1 en virgule flottante (float ou double, peu importe. Le mécanisme de virgule flottante ne peut pas représenter ce nombre.) Il n'y a que des approchés, donc de l'incertitude sur ce que ça donnera après traitement.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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
    Citation Envoyé par adiGuba Voir le message
    Salut,


    Ainsi le nombre 738290.76 est représenté sous la forme 73829076 * 102, avec un mantisse qui vaut 73829076 et un exposant qui vaut 2
    Mouais, sauf que c'est pas le cas des float, ils utilisent des puissances de 2 aps de 10, mais l'idée reste :p

    Le problème principal, comme l'a dit thelvin, c'est que les dixième, centième, etc ne sont pas réprésentables pas des puissance de deux. Ainsi, 0.1 en binaire, c'est

    0.000110011001100110011001100110011001100110011001100110011001....


    Donc c'est l'impossibilité d'avoir une conversion exacte de décimal vers binaire en terme de nombres réels. Mais en général, la différence est tellement loin derrière la virgule, qu'elle est couverte par l'arrondi de reconversion en décimal.

    Ensuite se rajoute la différence de précision entre float et double, qui fait que le float lors de sa reconversion vers du décimal a plus vite tendance à "déraper"

    Ton code fait décimal => binaire => décimal ce qui amène de la perte d'info. Vu les nombres que tu manipule, double a une précision a priori suffisante. Ton nombre vaut, exposant mis de coté, de l'ordre de 76 millions. Le float a une mantise avec une précision de 2^24, ce qui fait de l'ordre de 16 millions, tu est donc d'office dans une zone qui va déraper par manque de bits et tomber sur le nombre le plus proche. Le double a une mantise avec une précision de 53bits, ce est de l'ordre de beaucoup plus élevé que j'ai pas envie de calculer et n'induira pas pour tes nombre de problème.

  8. #8
    Membre à l'essai
    Inscrit en
    Juin 2008
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 16
    Points : 14
    Points
    14
    Par défaut
    c'est clair, merci beaucoup

    mon décimal est stocké en binaire avant d'être restitué et cette "reconstitution" de la valeur est incertaine.

  9. #9
    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
    Citation Envoyé par tchize_ Voir le message
    Mouais, sauf que c'est pas le cas des float, ils utilisent des puissances de 2 aps de 10, mais l'idée reste :p
    Oui en effet !

    Mais le problème est le même : quelque soit la puissance il est impossible de représenter toutes les valeurs possibles avec un type de taille fixe.
    Donc on aura toujours des imprécisions...


    a++

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

Discussions similaires

  1. Précision de types en perl
    Par Gnux dans le forum Langage
    Réponses: 7
    Dernier message: 08/11/2005, 08h31
  2. Précision du type float
    Par cj227854 dans le forum C
    Réponses: 5
    Dernier message: 02/11/2005, 20h54
  3. insérer une valeur de type float dans une abse de données
    Par Stephane_br dans le forum Langage SQL
    Réponses: 2
    Dernier message: 02/11/2005, 10h47
  4. Pb de formatage de champs de type float
    Par FrankyNormand dans le forum XMLRAD
    Réponses: 9
    Dernier message: 05/05/2005, 12h37
  5. [MS-SQL][ADO] précision du type FLOAT
    Par Le Lézard dans le forum Bases de données
    Réponses: 2
    Dernier message: 23/09/2004, 15h30

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