Pergunta

Estou tentando trabalhar com números grandes (~ 10 ^ 14) e preciso armazená-los e iterar em loops desse comprimento, ou seja,

n=SOME_BIG_NUMBER
do i=n,1,-1

Eu tentei a notação de estrela usual, kind=8 etc.Mas nada parece funcionar.Então eu verifiquei o huge função intrínseca e o código:

program inttest

print *,huge(1)
print *,huge(2)
print *,huge(4)
print *,huge(8)
print *,huge(16)
print *,huge(32)

end program inttest

produz o número 2147483647 em todos os casos.Por que é isso?Estou usando o gfortran (f95) em uma máquina de 64 bits.

Se vou precisar de uma biblioteca bignum, qual delas as pessoas sugerem?

Foi útil?

Solução

As versões do gfortran que uso, 4.3, 4.4 e 4.5 em um Mac, suportam números inteiros de 8 bytes.A melhor maneira de selecionar um tipo de variável em Fortran >= 90 é usar uma função intrínseca para especificar a precisão necessária.Tentar:

integer, parameter :: LargeInt_K = selected_int_kind (18)
integer (kind=LargeInt_K) :: i, n

para obter pelo menos 18 dígitos decimais, que normalmente serão um número inteiro de 8 bytes.

Com o gfortran 4.3, enormes (1_LargeInt_K) geram 9223372036854775807.Quando você escreveu enorme (1), etc., por padrão a constante era um número inteiro padrão, aqui evidentemente 4 bytes, já que enorme retornou 2147483647.Então, às vezes, você precisa especificar a precisão de constantes, não apenas de variáveis ​​- mais comumente, isso confunde as pessoas quando elas perdem algarismos significativos em uma constante real, cujo padrão é precisão única.

Veja também Fortran:inteiro*4 vs inteiro(4) vs inteiro(tipo=4)

Normalmente gfortran tem o nome de comando gfortran.O f95 poderia ser um compilador diferente?Experimente "gfortran -v" e "f95 -v".

Outras dicas

Você entendeu mal a definição precisa do HUGE função. HUGE(num) retorna o maior número com o mesmo tipo e tipo que num.O valor retornado também tem o mesmo tipo e tipo que num.Como todos os seus valores de entrada são números inteiros (padrão) HUGE, corretamente, retorna o maior número inteiro de tamanho padrão.

HUGE(num) não retorna o maior número inteiro com kind=num.Nem faz HUGE(num) retornar o maior número representável em num bytes.Embora muitos compiladores usem integer(kind=4) e integer(kind=8) etc. para números inteiros de 4 e 8 bytes, isso não é garantido pelo padrão de linguagem e não pode ser considerado portátil.

A resposta do @MSB diz como fazer o que você deseja, estou apenas introduzindo alguns esclarecimentos.

Resumo:Considere examinar as opções do compilador.

Já faz muito tempo que não faço FORTRAN e não me lembro de usar HUGE (), mas olhei um pouco para isso.Minha máquina Intel Linux possui gfortran 4.1.2.Descobri que precisava compilar com a opção -fdefault-integer-8 ativada para fazê-la funcionar com números inteiros de 64 bits.Especificamente, com este código:

      program inttest
      print *, huge(1)
      end program inttest

correndo

$ gfortran inttest.for

criou um executável que imprimiu:

2147483647

No entanto, executando:

$ gfortran -fdefault-integer-8 inttest.for

resultou em um executável que deu a saída:

9223372036854775807

Além disso, quando declarei uma variável como inteiro*8 e compilei sem a opção -fdefault-integer-8, recebi um erro.O código:

  program inttest2
  integer*8  test_int
  test_int = 9223372036854775807
  print *, test_int
  end program inttest2

correndo

$ gfortran inttest2.for

resultou em

No arquivo inttest.for:4

  test_int = 9223372036854775807  
                               1 

Erro:Número inteiro muito grande para seu tipo em (1)

No entanto, as coisas funcionaram bem quando compilei com a opção -fdefault-integer-8 e obtive um executável que imprimiu

9223372036854775807

Talvez existam outras opções de gfortran que seriam úteis, mas não investiguei mais.

É verdade que isso ainda não dá 10 ^ 14, mas pode ajudar a explicar os resultados que você viu.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top