2017-08-14 1 views
1

Dans Fortran, je souhaite pouvoir arrondir un grand flottant double précision à l'entier le plus proche. Je tenterai cela comme suit,Arrondir les grands flottants à l'entier

PROGRAM rounding 
IMPLICIT NONE 
INTEGER, PARAMETER :: DP = 8 
REAL(KIND=DP) :: value 

value = 12345678987.123456 

print *, CEILING(value) 

END PROGRAM ROUNDING 

Cependant, cela ne sort pas la bonne réponse, mais donne lieu -2147483648. J'apprécie que cela soit lié à la nature et à la précision des points flottants, mais arrondir un nombre comme celui-ci semble un objectif raisonnable.

Quelqu'un peut-il me diriger dans la bonne direction?

+0

Minor note: si 'value' est un nombre double précision, il vaut mieux écrire' value = 12345678987.123456_dp'. Sans le '_dp', vous affectez un seul nombre de précision à' value' et certains chiffres sont perdus. Dans votre cas, la différence dans l'entier résultant est '12345678848' vs' 12345678988'. –

Répondre

1

La variable entière renvoyée par ceiling() est de type trop petit pour contenir la valeur. Vous devez indiquer au plafond pour produire un entier d'un type plus grand. Sinon, il utilise l'entier par défaut.

Par exemple par

print *, CEILING(value, kind=dp) 

(en supposant qu'il existe ce genre, mais il devrait exister, si DP est sélectionné judicieusement)

Notez que la kind=8 est laid et non portable. Vous ne devez pas utiliser de constantes littérales telles que 8. Il n'y a aucune garantie qu'une telle sorte existe.

J'utiliserais:

INTEGER, PARAMETER :: DP = kind(1.d0) 

Pour l'entier genre vous pouvez utiliser SELECTED_INT_KIND pour sélectionner le type avec des chiffres assez comme

INTEGER, PARAMETER :: IP = SELECTED_INT_KIND(15) 

print *, CEILING(value, kind=IP) 

ou utiliser toute autre méthode de Fortran: integer*4 vs integer(4) vs integer(kind=4)

+0

La question initiale demande un 'entier le plus proche', qui ressemble plus à 'NINT' qu'à 'CEILING'. Mais le reste de la réponse, qui est la partie importante, est correct. – Ross