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

Ada Discussion :

Problème d'affichage avec les float


Sujet :

Ada

  1. #1
    Membre du Club Avatar de Poseidon62
    Inscrit en
    Mars 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Mars 2004
    Messages : 102
    Points : 67
    Points
    67
    Par défaut Problème d'affichage avec les float
    Bonjour,

    J'ai un petit problème avec les float.
    J'ai créé un code dans lequel j'ai mis une string en dur.
    Je la transforme en float, mais à l'affichage, le résultat diffère un peu

    Voici le code :
    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
    with Ada.Text_Io, Ada.Float_Text_Io;
    use Ada.Text_Io, Ada.Float_Text_Io;
    
    procedure Test_Float is
       
       Valeur : string := "123454.32";
       
       package Fonctions is
          function str_flt (X : String) return Float;
       end Fonctions;
       
       package body Fonctions is
          function str_flt (X : String) return Float is
             Value : Float;
          begin
             Value := Float'Value(X);
             return value;
          end Str_Flt;      
       end Fonctions;
       
    use fonctions;
       
    begin
       
       Put("La valeur Float de la chaine est : ");
       Put(Str_Flt(Valeur), 10, 4, 0);
       
    end test_float;
    Voici le résultat :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    La valeur Float de la chaine est :     123454.3203
    A quoi cela peut-il être dû ?

    Merci

  2. #2
    Membre habitué
    Inscrit en
    Décembre 2004
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 119
    Points : 156
    Points
    156
    Par défaut
    Citation Envoyé par Poseidon62
    Bonjour,

    J'ai un petit problème avec les float.
    J'ai créé un code dans lequel j'ai mis une string en dur.
    Je la transforme en float, mais à l'affichage, le résultat diffère un peu

    A quoi cela peut-il être dû ?

    Merci
    Probablement du au fait des imprecisions liees aux flottants.
    J'ai fait le test en utilisant un type digits 12 juste pour voir et la valeur "semble exacte" (a noter les guillemets, elle est "exacte" pour la precision demandee a l'affichage).

    Maintenant, la grande question est :
    De quelle precision exactement as-tu besoin?
    Car si tu as besoin d'un maximum de precision, alors le type standard float n'est probablement pas ton ami car c'est un digits 6 (en general).

    Pour plus de precision sur les type digits, jette un oeil au reference manual.

    A+

  3. #3
    Membre du Club Avatar de Poseidon62
    Inscrit en
    Mars 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Mars 2004
    Messages : 102
    Points : 67
    Points
    67
    Par défaut
    Slt et merci à toi jc,

    Maintenant, la grande question est :
    De quelle precision exactement as-tu besoin?
    En fait, ce sont des tests que j'effectue avant la "greffe" sur ma calculette.
    Donc, en ce qui concerne la précision, c'est une donnée inconnue à l'avance.
    Tout dépend de ce qui est entré par l'utilisateur.
    De plus, les deux opérandes peuvent être différents, car je peux avoir un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    45665.212 + 87853.66898498
    J'aurai voulu travailler avec des solutions du type unbounded_string, mais pour les nombres.

    Est-ce que cela existe ?

  4. #4
    Membre habitué
    Inscrit en
    Décembre 2004
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 119
    Points : 156
    Points
    156
    Par défaut
    Citation Envoyé par Poseidon62
    En fait, ce sont des tests que j'effectue avant la "greffe" sur ma calculette.
    Donc, en ce qui concerne la précision, c'est une donnée inconnue à l'avance.
    Tout dépend de ce qui est entré par l'utilisateur.
    Heu non.
    C'est a toi de definir la precision que tu veux autoriser.
    Donc si tu estimes que l'imprecision du type standard Float est un probleme pour ta calculette, alors change de type.

    [QUOTE]
    De plus, les deux opérandes peuvent être différents, car je peux avoir un truc du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    45665.212 + 87853.66898498
    Cf au-dessus, en fonction de la precision max que tu desires sur tes calculs, change ou non de type.
    Une calculette non plus ne fait pas de miracles, le constructeur a fait un choix de precision.

    AMA, utiliser des Long_Float sera suffisant.

  5. #5
    Membre du Club Avatar de Poseidon62
    Inscrit en
    Mars 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Mars 2004
    Messages : 102
    Points : 67
    Points
    67
    Par défaut
    Justement, j'ai fait un test pour obtenir les bornes des différents types :

    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
    89
    90
    91
    92
    with ada.text_io;
    use Ada.Text_Io;
     
    procedure Test_Int is
     
       package Lliio is new Integer_Io(Long_Long_Integer);
       use lliio;
       package Liio is new Integer_Io(Long_Integer);
       use Liio;
       package Siio is new Integer_Io(Short_Integer);
       use Siio;
       package Iio is new Integer_Io(Integer);
       use Iio;
     
       package Fio is new Float_Io(Float);
       use Fio;
       package Lfio is new Float_Io(Long_Float);
       use lfio;
       package Llfio is new Float_Io(Long_Long_Float);
       use Llfio; 
     
       A, B : long_float;
     
    begin
     
       Put_Line("Bornes sur les entiers : ");
       put_line("*************************");
     
       Put("Borne inferieure Lliio : ");
       Put(long_Long_Integer'First);
       New_Line;
     
       Put("Borne superieure Lliio : ");
       Put(long_Long_Integer'Last);
       New_Line;
     
       Put("Borne inferieure Liio  : ");
       Put(Long_Integer'First);
       New_Line;
     
       Put("Borne superieure Liio  : ");
       Put(Long_Integer'Last);
       New_Line;
     
       Put("Borne inferieure Siio  : ");
       Put(short_Integer'First);
       New_Line;
     
       Put("Borne superieure Siio  : ");
       Put(short_Integer'Last);
       New_Line;
     
       Put("Borne inferieure Iio   : ");
       Put(Integer'First);
       New_Line;
     
       Put("Borne superieure Iio   : ");
       Put(Integer'Last);
       New_Line(2);
     
       Put_Line("Bornes sur les reels : ");
       put_line("***********************");
     
       Put("Borne inferieure Fio   : ");
       Put(Float'First);
       New_Line;
     
       Put("Borne superieure Fio   : ");
       Put(Float'Last);
       New_Line;
     
       Put("Borne inferieure Lfio : ");
       Put(Long_float'First);
       New_Line;
     
       Put("Borne superieure Lfio : ");
       Put(Long_float'Last);
       New_Line;
     
       Put("Borne inferieure Llfio : ");
       Put(long_Long_Integer'First);
       New_Line;
     
       Put("Borne superieure Llfio : ");
       Put(long_Long_Integer'Last);
       New_Line;
     
       A := 16546546846.79769313486232;
       B := 6465.6546654655465465460;
       Put(A+B);
     
    End test_int;
    Résultat :
    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
    Bornes sur les entiers :
    *************************
    Borne inferieure Lliio : -9223372036854775808
    Borne superieure Lliio :  9223372036854775807
    Borne inferieure Liio  : -2147483648
    Borne superieure Liio  :  2147483647
    Borne inferieure Siio  : -32768
    Borne superieure Siio  :  32767
    Borne inferieure Iio   : -2147483648
    Borne superieure Iio   :  2147483647
     
    Bornes sur les reels :
    ***********************
    Borne inferieure Fio   : -3.40282E+38
    Borne superieure Fio   :  3.40282E+38
    Borne inferieure Lfio : -1.79769313486232E+308
    Borne superieure Lfio :  1.79769313486232E+308
    Borne inferieure Llfio : -9223372036854775808
    Borne superieure Llfio :  9223372036854775807
     1.65465533124524E+10
    Effectivement, si l'on considère qu'une calculette renvoie des puissances de 10 en fonction de la longueur, on dirait bien que çà fonctionne avec les long_float.

  6. #6
    Membre du Club Avatar de Poseidon62
    Inscrit en
    Mars 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Mars 2004
    Messages : 102
    Points : 67
    Points
    67
    Par défaut
    Justement, j'ai fait un test pour obtenir les bornes des différents types :

    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
    89
    90
    91
    92
    with ada.text_io;
    use Ada.Text_Io;
    
    procedure Test_Int is
       
       package Lliio is new Integer_Io(Long_Long_Integer);
       use lliio;
       package Liio is new Integer_Io(Long_Integer);
       use Liio;
       package Siio is new Integer_Io(Short_Integer);
       use Siio;
       package Iio is new Integer_Io(Integer);
       use Iio;
       
       package Fio is new Float_Io(Float);
       use Fio;
       package Lfio is new Float_Io(Long_Float);
       use lfio;
       package Llfio is new Float_Io(Long_Long_Float);
       use Llfio; 
       
       A, B : long_float;
    
    begin
    
       Put_Line("Bornes sur les entiers : ");
       put_line("*************************");
    
       Put("Borne inferieure Lliio : ");
       Put(long_Long_Integer'First);
       New_Line;
       
       Put("Borne superieure Lliio : ");
       Put(long_Long_Integer'Last);
       New_Line;
    
       Put("Borne inferieure Liio  : ");
       Put(Long_Integer'First);
       New_Line;
       
       Put("Borne superieure Liio  : ");
       Put(Long_Integer'Last);
       New_Line;
       
       Put("Borne inferieure Siio  : ");
       Put(short_Integer'First);
       New_Line;
       
       Put("Borne superieure Siio  : ");
       Put(short_Integer'Last);
       New_Line;
    
       Put("Borne inferieure Iio   : ");
       Put(Integer'First);
       New_Line;
       
       Put("Borne superieure Iio   : ");
       Put(Integer'Last);
       New_Line(2);
    
       Put_Line("Bornes sur les reels : ");
       put_line("***********************");
    
       Put("Borne inferieure Fio   : ");
       Put(Float'First);
       New_Line;
       
       Put("Borne superieure Fio   : ");
       Put(Float'Last);
       New_Line;
    
       Put("Borne inferieure Lfio : ");
       Put(Long_float'First);
       New_Line;
       
       Put("Borne superieure Lfio : ");
       Put(Long_float'Last);
       New_Line;
    
       Put("Borne inferieure Llfio : ");
       Put(long_Long_Integer'First);
       New_Line;
       
       Put("Borne superieure Llfio : ");
       Put(long_Long_Integer'Last);
       New_Line;
    
       A := 16546546846.79769313486232;
       B := 6465.6546654655465465460;
       Put(A+B);
       
    End test_int;
    Résultat :
    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
    Bornes sur les entiers :
    *************************
    Borne inferieure Lliio : -9223372036854775808
    Borne superieure Lliio :  9223372036854775807
    Borne inferieure Liio  : -2147483648
    Borne superieure Liio  :  2147483647
    Borne inferieure Siio  : -32768
    Borne superieure Siio  :  32767
    Borne inferieure Iio   : -2147483648
    Borne superieure Iio   :  2147483647
    
    Bornes sur les reels :
    ***********************
    Borne inferieure Fio   : -3.40282E+38
    Borne superieure Fio   :  3.40282E+38
    Borne inferieure Lfio : -1.79769313486232E+308
    Borne superieure Lfio :  1.79769313486232E+308
    Borne inferieure Llfio : -9223372036854775808
    Borne superieure Llfio :  9223372036854775807
     1.65465533124524E+10
    Effectivement, si l'on considère qu'une calculette renvoie des puissances de 10 en fonction de la longueur, on dirait bien que çà fonctionne avec les long_float.

  7. #7
    Membre éprouvé
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Points : 1 122
    Points
    1 122
    Par défaut
    jc-miranda, les flotants tels qu'implémentés dans le processeur n'imposent pas de limite de précision en eux même.

    Du moins il existe une limite, mais elle n'est pas donnée en nombre de chiffres.
    Avec des flotants de simple précision, la valeur la plus "proche de 0" que l'on peut avoir c'est 2^(-150) (à une puissance de 2 près), ce qui en base de 10 donne un truc pas loin de 10^(-45).

    Cette représentation des flotants en interne fait que certains nombres qui s'écrivent avec un nombre de chiffres fini en base 10, ne peuvent pas s'écrire de façon fini en base 2.
    Par exemple 0.1 en binaire s'écrit 0.00011001100110011...
    Or le nombre de bits utilisés pour représenter un flotant est fini, on peut donc ne pas retrouver sa valeur de départ en reconvertissant en base 10 après l'avoir converti en base 2 (passage obligé pour travailler avec en informatique).

    Et écrire un nombre en flotant ça revient à chercher E et M tels que le nombre soit égale à 2^(E-127)*(1+M*2^-23) (il y a aussi un bit de signe, mais c'est juste un bit en plus)

    Pour voir plus en détail comment ça marche, cf http://fr.wikipedia.org/wiki/Virgule_flottante

    À propos de ta valeur 123454.32, en binaire "simple" elle s'écrit comme ça (si on prend 24 bits significatifs comme avec les flotants simples) 11110001000111110.0101000, or comme les flotants ne sont jamais des valeurs exactes, lors de la conversion en base 10, pour arrondir il va considérer que tous les bits suivants sont à 1. Ce qui donne une valeur de 123454.32031249999[...] (cette valeur-ci à été calculée en précision arbitraire).

    Les erreurs d'arrondis sont une des limitations des flotants.
    L'autre limitation est que les opérations ne sont pas forcément significatives. Par exemple, ajouter 1 à la valeur 2^25 sera d'aucun effet (je parle toujours des flotants de simple précision). Mais de toutes façons ajouter 1 à une valeur aussi grande que 2^25 revient à ajouter "presque rien".

    Notez qu'en double précision on ne fait que rajouter des bits significatifs, les limites sont toujours là, mais elles se trouvent plus loin.

    Bien sûr, sur tout ça vous pourrez me dire que c'est le compilateur qui gère la représentation interne des flotants, mais je pense qu'il n'existe aucune implémentation qui va s'ammuser à refaire "à la main" des calculs sur des flotants alors que le processeur sait très bien le faire, et très rapidement en plus.

    Bref, tout ça pour dire que
    Car si tu as besoin d'un maximum de precision, alors le type standard float n'est probablement pas ton ami car c'est un digits 6 (en general).
    Ceci est faux, car un nombre flotant avec un nombre de chiffres-après-la-virgule fixé, n'est plus un flotant puisque par définition, un nombre à virgule flotant peut "déplacer" la virgule pour avoir la précision la plus optimale (grande précision pour les nombres proches de 0 et inversement).

    Poseidon62, par contre tu feras attention, tes long_long_float semblent avoir un interval de valeur bien plus court que les float normaux, de plus cet interval ressemble fort à celui des long_long_integer [2^(-63)-1 .. 2^64].


    Conclusion, à moins que tu veuille une calculatrice de précision totalement arbitraire (configurable et théoriquement infini) et que tu veuille t'ammuser à gérer toi-même les erreurs d'arrondi et tout, je te conseil d'utiliser des simples float, ou bien des long_float.
    Les vaches ne peuvent PAS voler, quoi qu'elles aient pu vous raconter.

  8. #8
    Membre habitué
    Inscrit en
    Décembre 2004
    Messages
    119
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 119
    Points : 156
    Points
    156
    Par défaut
    Citation Envoyé par Celelibi
    Bref, tout ça pour dire que Ceci est faux, car un nombre flotant avec un nombre de chiffres-après-la-virgule fixé, n'est plus un flotant puisque par définition, un nombre à virgule flotant peut "déplacer" la virgule pour avoir la précision la plus optimale (grande précision pour les nombres proches de 0 et inversement).
    Ou ai-je parler de nombres a virgule fixe? Oo

    Pour un type digits N, plus N est grand, plus sa mantisse est grande.
    Donc meilleure precision que le type standard digits 6 ......

    C'est tout ce que je voulais dire, probablement de facon pas tres claire si tu en viens a comprendre que je parlais de nombres a virgules fixes. :-?

  9. #9
    Membre du Club Avatar de Poseidon62
    Inscrit en
    Mars 2004
    Messages
    102
    Détails du profil
    Informations personnelles :
    Âge : 58

    Informations forums :
    Inscription : Mars 2004
    Messages : 102
    Points : 67
    Points
    67
    Par défaut
    Merci pour vos réponses.
    Je pense que je vais étudier le sujet.
    Il me semble que les long_float soient plus adaptés pour le coup.

    Par contre, au niveau, justement des long_float, les valeurs ne vous paraissent-elles pas bizarres
    Je ferai des essais et je vous tiens au courant.
    Pour le moment, je maintiens l'état "non résolu" pour ce post

    Merci à vous deux

  10. #10
    Membre éprouvé
    Avatar de Celelibi
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 087
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 087
    Points : 1 122
    Points
    1 122
    Par défaut
    jc-miranda meaculpa, dans ma tête j'ai associé les digits avec les delta-digits.

    Poseidon62, non c'est tout à fait normal.
    La valeur maximale représentable est quelque chose pas loin de 2^1024. Ce qui donne une valeur proche de 10^308.

    À noter que la précision maximale avec les digits est de 18 chiffres ce qui correspond aux flotants étends (ceux sur 80bits).
    Les long_float correspondent aux flotants double précision, donc 15 chiffres décimaux.
    Les vaches ne peuvent PAS voler, quoi qu'elles aient pu vous raconter.

Discussions similaires

  1. problème d'affichage avec les structures
    Par jlion5 dans le forum C
    Réponses: 1
    Dernier message: 03/05/2008, 13h13
  2. Problème d'affichage avec les lumières
    Par Glosialabolas dans le forum OpenGL
    Réponses: 3
    Dernier message: 02/11/2006, 18h46
  3. [PHP-JS] Problème d'affichage avec les ', ê, é,è
    Par cyberdevelopment dans le forum Langage
    Réponses: 4
    Dernier message: 28/07/2006, 13h49
  4. Problème de calcul avec les float
    Par Oberown dans le forum Général JavaScript
    Réponses: 8
    Dernier message: 24/05/2006, 09h28
  5. Réponses: 6
    Dernier message: 19/05/2005, 11h06

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