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

Fortran Discussion :

Cast Simple précision vers Double


Sujet :

Fortran

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut Cast Simple précision vers Double
    Bonjour,

    est ce qu'il existe une manière de caster un simple précision vers un double et qui en plus met à 0 les chiffres rajoutés par le cast?

    Exemple:
    REAL :: x =1.6

    REAL(x,KIND=8) j'aimerais avoir 1.60000000

    Merci d'avance

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Par défaut
    La réponse sera générale car je viens de changer d'ordinateur et je n'ai encore ni mes sources, ni de compilateur...

    La difficulté de ton problème est que tu vois la valeur en décimales alors qu'à l'interne, la valeur est représentée en binaire. Ainsi, 0.1 décimale est difficilement représentable en binaire. Ça vaut environ 1/16 + 1/32 + 1/256 + 1/512 + 1/4096 + 1/8192 + 1/65536 + 1/131072 + ... Dans ton exemple, tu vois 1.6, mais rien ne dit qu'à l'interne, ce n'est pas 1.599998. Veux-tu alors avoir 1.59999800000000 ? Par rapport à 1.6, est-ce plus précis que 1.5999986326484 ?

    Pour obtenir ce que tu veux, tu devras probalement forcer un arrondi par rapport au résultat des fonctions precision() et/ou spacing().

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut
    Je sais pour la représentation. Mais la valeur qui est rajouté à la fin c'est bien au hasard? (ça dépend ce qu'il y avait avant dans la mémoire non?)
    C'est ça que je n'aime pas. Vu que je fais une grosse somme de produit d'un Real avec un Double Precision j'ai peur que ça perturbe beaucoup mon résultat.

  4. #4
    Modérateur

    Profil pro
    Inscrit en
    Août 2006
    Messages
    974
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 974
    Par défaut
    Citation Envoyé par Keldran Voir le message
    Mais la valeur qui est rajouté à la fin c'est bien au hasard? (ça dépend ce qu'il y avait avant dans la mémoire non?)
    Je ne pense pas. Je ne connais pas vraiment ce sujet, mais je crois que le processeur ne fait « qu'ajouter des zéros », mais en binaire. En décimales, il est possible que tu vois des chiffres résultants de la conversion en décimales des fractions binaires. Dans mon exemple pour représenter 0.1, le terme 1/131072 vaut un bit en binaire, mais vaut 0.00000762939453125 en décimales. Le « bruit » que semble introduire la conversion est selon moi la conséqquance de la perte de précision initiale lors de la conversion (lecture) de décimale à binaire, perte que tu ne peux évidemment récupérer en convertissant de simple précision à double précision.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2009
    Messages : 18
    Par défaut
    D'accord, merci pour la réponse. Je pensais vraiment que c'était aléatoire les valeurs qu'on pouvait lire quand on passait d'un float à un double.

  6. #6
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut melasse numerique
    bonjour
    c'est une melasse et non plus un calcul.
    il y a une mantisse et un exposant.
    simple precision 32 bits:
    -bit signe :1
    -exposant : sur 8 bits
    -mantisse sur 23 bits =>approximativ.7 chiffres decimaux,23Log(2)base10=6.923

    double precision :64 bits
    - bit signe :1
    - exposant :sur 11 bits
    - mantisse :sur 52 bits =>approximativ.16 choffres decimaux,53Log(2)base10=15.955

    Dans ton cas ou tu caste vers un type dont la precision est plus grande c'est archi-clair .
    Qui peut le plus peut le moins .
    La mantisse du double precision etant plus grande ,il ne faut pas sortir de saint cyr pour voir que le simple precision sera contenu integralement dans la mantisse du double sans perte de precision.
    Les choses seraient effectivement dramatiques si tu faisais l'inverse ,caster du double vers le simple ,parce la majorite des compilateurs font la troncature de ce qui deborde par le bas naturellement pour la mantisse et pour l'exposant.

    1er exemple de double a simple:
    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
     
    !  --------------------------------------------------
    !  Silverfrost FTN95 for Microsoft Visual Studio
    !  Free Format FTN95 Source File
    !  --------------------------------------------------
     
    !Exemple des fonctions FCORE4 et DCORE8 du Silverfrost Fortran
    !Elles donnent la representation interne machine.
    PROGRAM test
            REAL*4 :: r4
            REAL*8 :: r8
     
           !de simple precision à double
     
            r4= 1.6
     
            r8 = r4
     
            PRINT*,"r4: ",r4 
            PRINT*,"code r4: ",FCORE4(loc(r4)) 
     
            PRINT*,"r8:" ,r8
            PRINT*,"core r8:" ,DCORE8(loc(r8))
     pause
    END
    !resultats
    ! r4  :          1.60000
    ! core r4:     1.60000
    ! r8  :          1.60000002384
    ! dcore r8:     1.60000002384
    De double à simple precision voici un exemple edifiant de perte de precision:

    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
     
    !Exemple des fonctions FCORE4 et DCORE8 du Silverfrost Fortran
    !Elles donnent la representation interne machine.
    PROGRAM Test2
            REAL*4 :: r4
            REAL*8 :: r8
            REAL*4 :: r44
            REAL*8 :: r88
            !de  double  à  simple precision grands nombres
            !j'ai pris en sens inverse expres le meme nombre
     
            r8 =  1.60000002384
            r4= r8
     
            PRINT*,"r8:" ,r8
            PRINT*,"core r8:" ,DCORE8(loc(r8))
     
            PRINT*,"r4: ",r4 
            PRINT*,"code r4: ",FCORE4(loc(r4)) 
     
     
     
            !de  double  à  simple precision grands nombres(influence de l'exposant)
           ! plus grand exposant pour :
           !r4 : 2 puissance 127  => 10 puissance 39
           !r8  :2 puissance 1023 => 10 puissance 308 
           !NB: si met r88 = 0.25e+40 il plante:number out if range car  simple precision
           !ne peut avoir un exposant de plus de 39
     
            r88 = 0.25e+39
            r44 = rr8
     
     
            PRINT*,"r88:" ,r88
            PRINT*,"core r8:" ,DCORE8(loc(r88))
     
            PRINT*,"r44: ",r44 
            PRINT*,"code r44: ",FCORE4(loc(r44)) 
     pause
    END
     
    !resultats
    !r8:          1.60000002384
    !core r8:          1.60000002384
    !r4:      1.60000
    !code r4:      1.60000
    !
    !resultats avec exposant en limite
    !
    !r88:       2.500000072190E+38
    !core r8:       2.500000072190E+38
    !r44:      0.00000
    !code r44:      0.00000
    Il faut mediter sur les calculs et le choix des types au depart et pas en cours de route...
    Bon code...

  7. #7
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut melasse numerique
    bonjour
    c'est une melasse et non plus un calcul.
    il y a une mantisse et un exposant.
    simple precision 32 bits:
    -bit signe :1
    -exposant : sur 8 bits
    -mantisse sur 23 bits =>approximativ.7 chiffres decimaux,23Log(2)base10=6.923

    double precision :64 bits
    - bit signe :1
    - exposant :sur 11 bits
    - mantisse :sur 52 bits =>approximativ.16 choffres decimaux,53Log(2)base10=15.955

    Dans ton cas ou tu caste vers un type dont la precision est plus grande c'est archi-clair .
    Qui peut le plus peut le moins .
    La mantisse du double precision etant plus grande ,il ne faut pas sortir de saint cyr pour voir que le simple precision sera contenu integralement dans la mantisse du double sans perte de precision.
    Les choses seraient effectivement dramatiques si tu faisais l'inverse ,caster du double vers le simple ,parce la majorite des compilateurs font la troncature de ce qui deborde par le bas naturellement pour la mantisse et pour l'exposant.

    1er exemple de double a simple:
    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
     
    !  --------------------------------------------------
    !  Silverfrost FTN95 for Microsoft Visual Studio
    !  Free Format FTN95 Source File
    !  --------------------------------------------------
     
    !Exemple des fonctions FCORE4 et DCORE8 du Silverfrost Fortran
    !Elles donnent la representation interne machine.
    PROGRAM test
            REAL*4 :: r4
            REAL*8 :: r8
     
           !de simple precision à double
     
            r4= 1.6
     
            r8 = r4
     
            PRINT*,"r4: ",r4 
            PRINT*,"code r4: ",FCORE4(loc(r4)) 
     
            PRINT*,"r8:" ,r8
            PRINT*,"core r8:" ,DCORE8(loc(r8))
     pause
    END
    !resultats
    ! r4  :          1.60000
    ! core r4:     1.60000
    ! r8  :          1.60000002384
    ! dcore r8:     1.60000002384
    De double à simple precision voici un exemple edifiant de perte de precision:

    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
     
    !Exemple des fonctions FCORE4 et DCORE8 du Silverfrost Fortran
    !Elles donnent la representation interne machine.
    PROGRAM Test2
            REAL*4 :: r4
            REAL*8 :: r8
            REAL*4 :: r44
            REAL*8 :: r88
            !de  double  à  simple precision grands nombres
            !j'ai pris en sens inverse expres le meme nombre
     
            r8 =  1.60000002384
            r4= r8
     
            PRINT*,"r8:" ,r8
            PRINT*,"core r8:" ,DCORE8(loc(r8))
     
            PRINT*,"r4: ",r4 
            PRINT*,"code r4: ",FCORE4(loc(r4)) 
     
     
     
            !de  double  à  simple precision grands nombres(influence de l'exposant)
           ! plus grand exposant pour :
           !r4 : 2 puissance 127  => 10 puissance 39
           !r8  :2 puissance 1023 => 10 puissance 308 
           !NB: si met r88 = 0.25e+40 il plante:number out if range car  simple precision
           !ne peut avoir un exposant de plus de 39
     
            r88 = 0.25e+39
            r44 = rr8
     
     
            PRINT*,"r88:" ,r88
            PRINT*,"core r8:" ,DCORE8(loc(r88))
     
            PRINT*,"r44: ",r44 
            PRINT*,"code r44: ",FCORE4(loc(r44)) 
     pause
    END
     
    !resultats
    !r8:          1.60000002384
    !core r8:          1.60000002384
    !r4:      1.60000
    !code r4:      1.60000
    !
    !resultats avec exposant en limite
    !
    !r88:       2.500000072190E+38
    !core r88:       2.500000072190E+38
    !r44:      0.00000
    !code r44:      0.00000
    Il faut mediter sur les calculs et le choix des types au depart et pas en cours de route...
    Bon code...

Discussions similaires

  1. Simple cote et double cote en SQL
    Par dany108 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 19/07/2006, 06h41
  2. Problème étrange de précision avec double
    Par titoine1978 dans le forum DirectX
    Réponses: 4
    Dernier message: 22/02/2006, 09h26
  3. Problème conversion float vers double
    Par jhenaff dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 27/01/2006, 10h39
  4. [MySQL] transformer une simple quote en double pour un insert !!
    Par st0nky dans le forum PHP & Base de données
    Réponses: 2
    Dernier message: 11/01/2006, 16h38
  5. Cast de string vers Integer
    Par MachProd dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 16/11/2005, 15h55

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