Длинные целые в Фортране - PullRequest
4 голосов
/ 08 июля 2010

Я пытаюсь работать с большими числами (~ 10 ^ 14), и мне нужно иметь возможность хранить их и перебирать циклы такой длины, т.е.

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

Я пробовалобычная звездная запись, kind=8 и т. д., но ничего не работает.Затем я проверил встроенную функцию huge и код:

program inttest

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

end program inttest

во всех случаях выдает число 2147483647.Почему это?Я использую gfortran (f95) на 64-битной машине.

Если мне понадобится библиотека bignum, какую из них предложат люди?

Ответы [ 3 ]

8 голосов
/ 08 июля 2010

Вы неправильно поняли точное определение функции HUGE. HUGE(num) возвращает наибольшее число того же типа и типа, что и num. Возвращаемое значение также имеет тот же тип и тип, что и num. Поскольку все ваши входные значения (по умолчанию) целые числа HUGE, правильно, возвращает наибольшее целое число по умолчанию.

HUGE(num) не возвращает наибольшее целое число с kind=num. Также HUGE(num) не возвращает наибольшее число, представимое в num байтах. Хотя многие компиляторы используют integer(kind=4) и integer(kind=8) и т. Д. для 4- и 8-байтовых целых чисел, это не гарантируется стандартом языка и не может считаться переносимым.

@ В ответе MSB рассказывается, как делать то, что вы хотите, я просто уточняю.

7 голосов
/ 08 июля 2010

Версии gfortran, которые я использую, 4.3, 4.4 и 4.5 на Mac, поддерживают 8-байтовые целые числа. Лучший способ выбрать тип переменной в Fortran> = 90 - использовать встроенную функцию для определения необходимой точности. Попробуйте:

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

для получения не менее 18 десятичных цифр, которые обычно представляют собой 8-байтовые целые числа.

В gfortran 4.3 огромный (1_LargeInt_K) выводит 9223372036854775807. Когда вы пишете огромный (1) и т. Д., По умолчанию константа была целым числом по умолчанию, здесь, очевидно, 4 байта, поскольку огромный возвращается 2147483647. Поэтому иногда вам нужно указать Точность констант, а не только переменных - чаще всего это сбивает людей с толку, когда они теряют значащие цифры из-за реальной константы, которая по умолчанию имеет одинарную точность.

Также см. Фортран: целое число * 4 против целого числа (4) против целого числа (вид = 4)

Обычно gfortran имеет имя команды gfortran. Может ли f95 быть другим компилятором? Попробуйте "gfortran -v" и "f95 -v".

0 голосов
/ 08 июля 2010

Резюме: рассмотрите возможность просмотра параметров компилятора.

Прошло много времени с тех пор, как я сделал FORTRAN, и я не помню, чтобы использовал HUGE (), но я немного посмотрел на это.Моя машина Intel Linux имеет gfortran 4.1.2.Я обнаружил, что должен был скомпилировать с включенной опцией -fdefault-integer-8, чтобы она работала для 64-битных целых чисел.В частности, с помощью этого кода:

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

выполняется

$ gfortran inttest.for

создал исполняемый файл, который напечатал:

2147483647

Однако, выполнение:

$ gfortran -fdefault-integer-8 inttest.for

привело кисполняемый файл, который дал вывод:

9223372036854775807

Кроме того, когда я объявил переменную как целое число * 8 и скомпилировал без опции -fdefault-integer-8, я получилошибка.Код:

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

работает

$ gfortran inttest2.for

привело к

В файле inttest.for: 4

  test_int = 9223372036854775807  
                               1 

Ошибка: целое число слишком большое для его вида в (1)

Однако все работало нормально, когда я скомпилировал с -fdefault-integer-8вариант, и я получил исполняемый файл, который напечатал

9223372036854775807

Возможно, есть другие варианты gfortran, которые были бы полезны, но я не стал исследовать дальше.

Конечно, это не даст вам 10 ^ 14, но может помочь объяснить результаты, которые вы видели.

...