1. #1
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 299
    Points : 8 645
    Points
    8 645

    Par défaut Question sur les informations de l'aide sur les types réels et résultats de calculs

    Bonjour,

    Suite à des tests faits pour un autre problème (n'ayant rien à voir avec Lazarus), j'ai quand même découvert un truc bizarre dont je voulais vous faire part.

    Posons le décor avec un extrait de l'aide (en rouge un truc rajouté par moi) :
    Nom : real_types.png
Affichages : 58
Taille : 49,9 Ko

    Ce qui m'intéresse c'est la 3e colonne, "Significant digits" : vous traduisez ça comment ? "Chiffres significatifs" ? Et les autres chiffres on en fait quoi ?
    Et puis d'abord, pourquoi deux valeurs ? 7-8 pour le type Single, ça dépend de quoi ? De l'air du temps ? De l'âge du capitaine ? D'autre chose ?

    Parce que ce matin, j'avais le nez dans des tests de divisions, et je vous laisse regarder les résultats de ShowMessage(FloatToStr(la_division)); en fonction du Type de la_division :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    avec 841.0 / 108.0    
     single 7.787036896           9 chiffres décimaux
     double 7.78703703703704     14 chiffres décimaux 
     
    avec  16.0 / 116.0      
     single 0.137931034           9 chiffres décimaux
     double 0.137931034482759    15 chiffres décimaux 
     
    avec 216.0 / 24389.0     
     single 0.00885645207        11 chiffres décimaux
     double 0.00885645167903563  17 chiffres décimaux
    J'avoue ne pas comprendre cette 3e colonne (c'est pas un film, ça ? )
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  2. #2
    Membre confirmé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    octobre 2009
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : octobre 2009
    Messages : 118
    Points : 555
    Points
    555

    Par défaut

    Bonjour,

    Citation Envoyé par Jipété
    Ce qui m'intéresse c'est la 3e colonne, "Significant digits" : vous traduisez ça comment ? "Chiffres significatifs" ? Et les autres chiffres on en fait quoi ?
    Et puis d'abord, pourquoi deux valeurs ? 7-8 pour le type Single, ça dépend de quoi ? De l'air du temps ? De l'âge du capitaine ? D'autre chose ?
    Je ne doute pas qu'un mathématicien ne puisse nous donner une explication dans un langage que seul un "matheux" pourrait comprendre mais à mon modeste niveau je vais tenter une explication fondée sur l'implémentation binaire des réels en point flottant et en simplifiant au maximum.

    Je précise bien "en point flottant": Single, Double et Extended en sont (alors que Currency est un réel "point fixe" et Comp est une variante d'int64 spécifique au co-processeur arithmétique Intel). Avec FPC, le type Real lui est un allias pour Single, Double ou Extended selon la plateforme ciblée.

    La représentation binaire d'un réel point flottant comprend trois champs :
    • Un bit de signe
    • Quelques bits pour l'exposant qui est en quelque sorte un facteur d'échelle par lequel doit être multiplié le significande.
    • Les bits restants pour le significande (ou mantisse) qui représente les chiffres significatifs du nombre, indépendamment de la position de la virgule décimale (qui elle dépend de la valeur de l'exposant, d'où l'appellation "point flottant"). Le significande est en principe cadré de façon à ce que son premier bit à 1 de poids le plus fort coïncide avec le bit de plus haut rang de la zone.


    Ce préalable étant posé prenons l'exemple du type Single :

    Dans un Single le significande est codé sur 23 bits (avec 8 pour l'exposant et 1 pour le signe, celà fait 32 bits).

    Par conséquent la valeur binaire des significandes utilisant la plage de précision maximale, c'est à dire la totalité des 23 bits disponibles, peut aller de (2 puissance 23) à (2 puissance 24)-1 ce qui en décimal représente un intervalle allant de 8 388 608 (7 chiffres décimaux) à 16 777 215 (8 chiffres décimaux), d'où le 7-8 figurant dans la 3ème colonne du tableau.

    Raisonnement similaire pour Double (significande sur 52 bits) et Extended (significande sur 63 bits).

    En conclusion, les tests de divisions présentés ne présentent pas pour moi d'anomalie flagrante en ce sens que c'est bien au niveau du 7ème ou 8ème chiffre significatif qu'apparait une divergence entre Single et Double (les zéros de tête, avant ou après le point décimal, doivent être considérés comme non significatifs). Tout au plus pourrait-on reprocher à FloatToStr(single) de générer trop de chiffres (9 ou 10) alors que l'on peut s'interroger sur leur exactitude au delà du 7ème ou 8ème.

  3. #3
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 299
    Points : 8 645
    Points
    8 645

    Par défaut

    Bonsoir et merci pour cette réponse détaillée.

    Il me reste un soupçon de brouillard, caché entre parenthèses :
    Citation Envoyé par DomDA91 Voir le message
    (les zéros de tête, avant ou après le point décimal, doivent être considérés comme non significatifs).
    Si ça ne t'ennuie pas, tu me feras un chèque de 0,9 € plutôt qu'un de 0,00000009 €, : ça sera plus vite écrit et tu feras des économies d'encre,

    Ou je n'ai pas compris ce que tu veux dire (j'ai un peu wikipédié, mais les maths et moi, à ce niveau-là, je commence à avoir du mal...)
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Membre confirmé

    Homme Profil pro
    Rédacteur technique (retraité)
    Inscrit en
    octobre 2009
    Messages
    118
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 75
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique (retraité)

    Informations forums :
    Inscription : octobre 2009
    Messages : 118
    Points : 555
    Points
    555

    Par défaut

    Désolé de n'avoir pas été clair. Ce que je voulais dire c'est que ces zéros à gauche ne s'imputaient pas sur l'encodage du significande, mais cela ne voulais pas dire qu'ils étaient complètement ignorés. En effet les zéros situés entre la virgule décimale et le premier chiffre non-zéro sont bel et bien pris en compte pour le calcul de l'exposant. C'est très apparent par exemple si on exprime ton exemple (0,9 et 0,0000009) en notation scientifique :

    0,9 ---> 9E-1
    0,00000009 --> 9E-8

    Le 9 avant le E est le significande et est identique dans les deux cas.
    C'est seulement l'exposant qui change et si on fait leur différence : (8 - 1 = 7) on à bien le nombre de zéros entre la virgule et le 9.

    Par conséquent la précision du significande n'est pas diminuée par la présence des zéros et reste dans les deux cas à 7-8 chiffres décimaux pour un Single.

    C'est à la routine de conversion qu'il incombe de correctement analyser le significande et l'exposant afin de re-générer les zéros qui manquent.

    A ce propos, j'ai essayé le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Edit1.Caption:= FloatToStr(Single(1 / 3));
    et ça me renvoie : 0,3333333433

    Curieux ce 4 au milieu des 3 ! Et en huitième position justement !
    Pour Double c'est correct, il y a décidément quelque chose qui cloche dans cette routine.

  5. #5
    Expert éminent
    Avatar de Jipété
    Profil pro
    Inscrit en
    juillet 2006
    Messages
    6 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : juillet 2006
    Messages : 6 299
    Points : 8 645
    Points
    8 645

    Par défaut

    Citation Envoyé par DomDA91 Voir le message
    Désolé de n'avoir pas été clair.
    Pas de souci.
    Allez hop !,


    Citation Envoyé par DomDA91 Voir le message
    C'est à la routine de conversion qu'il incombe de correctement analyser le significande et l'exposant afin de re-générer les zéros qui manquent.

    A ce propos, j'ai essayé le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Edit1.Caption:= FloatToStr(Single(1 / 3));
    et ça me renvoie : 0,3333333433

    Curieux ce 4 au milieu des 3 ! Et en huitième position justement !
    Pour Double c'est correct,
    Confirmé dans mon vieux 2.6.2/1.4

    Citation Envoyé par DomDA91 Voir le message
    il y a décidément quelque chose qui cloche dans cette routine.
    Au secours !


    EDIT :
    Bon, j'ai fait un test ultra-rapide en C, ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0.33333334326744079589843750000000
    0.33333333333333331482961625624739
    0.33333333333333331482961625624739
    Le code :
    Code C : 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
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
    int main(int argc, char **argv)
    {
    //        taille mémoire --  précision (décimal)
      float f;  // 4 octets  --  6 chiffres après la virgule
      double d; // 8 "       -- 15 " "
      long double l; // 10 " -- 19 " "
     
      f = 1.0 / 3.0;
      d = 1.0 / 3.0;
      l = 1.0 / 3.0;
     
      printf( "%.32f\n",  f );
      printf( "%.32f\n",  d );
      printf( "%.32Lf\n", l );
     
    	return 0;
    }

    Maintenant, si je respecte les infos de mon petit bouquin (C précis et concis, chez O'Reilly, pas tout jeune), je réécris avec
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      printf( "%.6f\n",  f );
      printf( "%.15f\n",  d );
      printf( "%.19Lf\n", l );

    et tout va bien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    0.333333
    0.333333333333333
    0.3333333333333333148
    Il faudrait peut-être s'astreindre à tronquer les résultats de FloatToStr en fonction du tableau que j'ai posté, non ?
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  6. #6
    Membre régulier
    Homme Profil pro
    Inscrit en
    février 2013
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations forums :
    Inscription : février 2013
    Messages : 33
    Points : 82
    Points
    82

    Par défaut

    En utilisant ce code qui sert à évaluer la précision numérique, je n'ai pas été en mesure d’observer une différence significative entre les divers type de réels. C'était prévisible par ce que quelque soit le type de la variable x, elle subit une promotion en float lors de l'appel de la fonction LN.

    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
     
    TypeReel=single;
     
    Function VerifierPrecisionNumerique:Extended;
     
    CONST
      Limite= 1000000;
    VAR
      x: TypeReel;
      Delta: Extended;
      i: Cardinal;
    Begin
      Delta:=0.0;
      Randomize;
     
      FOR i:= 1 To Limite DO
      BEGIN
         x:=Random*10000+0.0000001;
         Delta+= ABS(TAN(ArcTAN2(SQRT(SQR(EXP(LN(x)))),1))-x);
      End;
     
      Result:=Delta
    End;

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

Discussions similaires

  1. Imprimer les informations d'un enregistrement sur deux pages
    Par Shalfx dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 04/03/2016, 21h30
  2. [PHP 5.6] Impossible de lister les informations d'une table sur PHP
    Par xnooztv1 dans le forum Langage
    Réponses: 1
    Dernier message: 19/10/2015, 21h03
  3. [MySQL-5.6] Impossible de lister les informations d'une table sur PHP
    Par xnooztv1 dans le forum Requêtes
    Réponses: 0
    Dernier message: 19/10/2015, 18h52
  4. Sauvegarder les informations d'une listbox sur une feuille
    Par rafikiderevel dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 01/06/2015, 16h45

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