2012-04-09 2 views
3

J'ai un code Fortran étant compilé en gfortran (plusieurs milliers de lignes, donc je vais essayer d'afficher les lignes importantes) qui me donne:Fortran: Modification possible de la valeur

nrev(isat)=dint((t_ref-t_in)/zper)+1 
      1 
Warning:Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) 

Ils sont initialisés comme:

integer*4 nrev(nmaxsat) 
integer*4 isat 
real*8  t_ref 
real*8  t_in 
real*8  zper 

Des idées sur la façon de résoudre ce problème? Merci!

+0

Que voulez-vous corriger, exactement? En fonction de l'amplitude de l'expression de double précision, il ne sera pas représentable comme un entier signé de 32 bits. Qu'attendez-vous qu'il se passe? – talonmies

+0

Lorsque j'exécute le programme complet, toutes les valeurs de sortie sont NaN, donc je suis préoccupé par des avertissements comme celui-ci sont le problème. Je ne ai pas d'erreurs lors de la compilation dans gfortran, mais il compile et s'exécute correctement lorsqu'il est compilé en g77. J'ai plusieurs de ces avertissements, mais je me concentre sur celui-ci en espérant que si je peux obtenir de l'aide avec un, je peux comprendre le reste. –

+0

Si vous obtenez des valeurs NaN, cela signifie que vous avez un calcul de virgule flottante non valide quelque part. Le code que vous avez montré calcule une valeur entière. Il est impossible de dire comment les deux pourraient être liés en fonction de ce que vous avez posté. – talonmies

Répondre

4

C'est une excellente idée de se débarrasser de tous les avertissements, même minimes - même si seulement quand vous avez des problèmes plus importants, vous les voyez plutôt que d'avoir la sortie submergée par de petites choses.

Dans ce cas, le message d'avertissement est assez clair; vous affectez un double à un entier. Le dint tronque intrinsèque, mais ne convertit pas les types; Vous attribuez donc une valeur de double précision dont la valeur est tronquée à un nombre entier. Vous pourriez à juste titre noter que l'intrinsèque porte un nom prêtant à confusion, mais ...

Si vous voulez effectuer la conversion ainsi que la troncature, idint est réellement converti en nombre entier.

Ainsi par exemple ce programme

program foo 

    integer :: nrev 
    double precision :: t_ref 

    t_ref = 1. 

    nrev = dint(t_ref) 

end program foo 

crée le même avertissement:

$ gfortran -o foo foo.f90 -Wall -std=f95 
foo.f90:8.11: 

    nrev = dint(t_ref) 
      1 
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) 

Mais celui-ci est bien:

program foo 

    integer :: nrev 
    double precision :: t_ref 

    t_ref = 1. 

    nrev = idint(t_ref) 

end program foo 

comme nous le voyons:

$ gfortran -o foo foo.f90 -Wall -std=f95 
$ 
+6

Au lieu d'utiliser le "idint" intrinsèque spécifique, vous pouvez utiliser le nom générique "int". Avec le générique, le compilateur détermine automatiquement quelle fonction utiliser du type de l'argument et le programmeur n'a pas à se souvenir du nom. (Il existe également un second argument dans lequel vous pouvez spécifier le type de l'entier renvoyé par la fonction.) –

+0

Merci beaucoup pour cette explication! Cela m'aidera à nettoyer ce code et à le faire fonctionner beaucoup mieux. J'ai demandé ceci dans un commentaire ci-dessus, mais pouvez-vous expliquer quelle est la différence entre les "avertissements possibles de changement de valeur dans la conversion" et les avertissements "incompatibilité de type dans l'argument"? Ils me semblent dire la même chose de deux façons différentes ... Merci encore! –

Questions connexes