Long ints en Fortran
-
13-09-2020 - |
Question
Je suis en train de travailler avec un grand nombre (~10^14), et j'ai besoin d'être en mesure de les stocker et de les répéter sur les boucles de longueur, c'est à dire
n=SOME_BIG_NUMBER
do i=n,1,-1
J'ai essayé d'habitude étoiles de notation, kind=8
etc.mais rien ne semble fonctionner.Puis j'ai vérifié le huge
fonction intrinsèque, et le code:
program inttest
print *,huge(1)
print *,huge(2)
print *,huge(4)
print *,huge(8)
print *,huge(16)
print *,huge(32)
end program inttest
produit le numéro 2147483647 dans tous les cas.Pourquoi est-ce?Je suis en utilisant gfortran (f95) sur une machine 64 bits.
Si je vais avoir besoin d'un bignum de la bibliothèque, qui ne suggèrent?
La solution
Le gfortran les versions que j'utilise, 4.3, 4.4 et 4.5 sur un Mac, prise en charge de 8 octets entiers.La meilleure façon de sélectionner un type de variable en Fortran >= 90 est d'utiliser une fonction intrinsèque de spécifier la précision dont vous avez besoin.Essayez:
integer, parameter :: LargeInt_K = selected_int_kind (18)
integer (kind=LargeInt_K) :: i, n
pour obtenir au moins 18 chiffres après la virgule, qui sera généralement un entier de 8 octets.
Avec gfortran 4.3, énorme (1_LargeInt_K) sorties 9223372036854775807.Quand vous avez écrit énorme (1), etc., par défaut, la constante a une valeur par défaut entier, ici évidemment de 4 octets depuis l'énorme retourné 2147483647.Alors, parfois, vous avez besoin de spécifier la précision des constantes, et pas seulement les variables -- plus souvent il s'agit de voyages les gens quand ils perdent des chiffres significatifs sur une vraie constante, dont la valeur par défaut de précision unique.
Voir aussi Fortran:integer*4 vs integer(4) vs integer(kind=4)
Généralement gfortran a le nom de la commande gfortran.Pourrait f95 être un compilateur différent?Essayez "gfortran -v" et "f95 -v".
Autres conseils
Vous avez mal compris la définition précise de la HUGE
fonction. HUGE(num)
retourne le plus grand nombre avec le même genre et type de num
.La valeur retournée a aussi le même genre et de même type que num
.Depuis tous vos valeurs d'entrée (par défaut) des entiers HUGE
, correctement, renvoie la plus grande valeur par défaut de la taille d'un entier.
HUGE(num)
ne retourne pas le plus grand entier avec kind=num
.Ni ne HUGE(num)
de retour le plus grand nombre représentable dans num
octets.Alors que de nombreux compilateurs utilisation integer(kind=4)
et integer(kind=8)
etc 4 et 8 octets entiers, ce n'est pas garanti par la norme du langage et ne peut être invoquée pour être portable.
@ESM réponse vous dit comment faire ce que vous voulez, je suis juste un coup avec quelques précisions.
Résumé:Pensez regarder les options du compilateur.
Il a été l'-sur-g temps depuis que je l'ai fait FORTRAN, et je ne me souviens pas de l'aide ÉNORME(), mais j'ai regardé un peu.Mon Intel machine Linux a gfortran 4.1.2.J'ai trouvé, j'ai dû compiler avec l'option-fdefault-entier-8 option est activée pour le faire fonctionner pour les entiers 64 bits.Plus précisément, avec ce code:
program inttest
print *, huge(1)
end program inttest
l'exécution de
$ gfortran inttest.pour
créé un fichier exécutable qui a imprimé:
2147483647
Toutefois, en cours d'exécution:
$ gfortran -fdefault-entier-8 inttest.pour
entraîné dans un fichier exécutable qui a donné à la sortie:
9223372036854775807
Aussi, quand j'ai déclaré une variable integer*8 et compilé sans le -fdefault-entier-8 option, j'ai eu une erreur.Le code:
program inttest2
integer*8 test_int
test_int = 9223372036854775807
print *, test_int
end program inttest2
l'exécution de
$ gfortran inttest2.pour
entraîné dans
Dans le fichier inttest.pour:4
test_int = 9223372036854775807 1
Erreur:Entier trop grand pour sa nature (1)
Cependant, les choses ont bien fonctionné lorsque j'ai compilé avec l'option-fdefault-entier-8 et j'ai un exécutable qui a imprimé
9223372036854775807
Peut-être il y a d'autres gfortran options qui seraient utiles, mais je n'ai pas d'autres investigations.
Accordé, ce n'est toujours pas obtenir de vous 10^14, mais il peut aider à expliquer les résultats que vous avez vu.