Длинные целые числа в Фортране
-
13-09-2020 - |
Вопрос
Я пытаюсь работать с большими числами (~ 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, какую из них посоветуют люди?
Решение
Версии gfortran, которые я использую, 4.3, 4.4 и 4.5 на Mac, поддерживают 8-байтовые целые числа.Лучший способ выбрать тип переменной в Фортране >= 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».
Другие советы
Вы неправильно поняли точное определение понятия HUGE
функция. HUGE(num)
возвращает наибольшее число того же вида и типа, что и num
.Возвращаемое значение также имеет тот же вид и тип, что и num
.Поскольку все ваши входные значения являются целыми числами (по умолчанию) HUGE
, правильно, возвращает наибольшее целое число размера по умолчанию.
HUGE(num)
не возвращает наибольшее целое число с kind=num
.И не HUGE(num)
вернуть наибольшее число, представимое в num
байты.Хотя многие компиляторы используют integer(kind=4)
и integer(kind=8)
и т. д. для 4- и 8-байтовых целых чисел это не гарантируется стандартом языка и не может считаться переносимым.
Ответ @MSB расскажет вам, как делать то, что вы хотите, я просто вставляю некоторые разъяснения.
Краткое содержание:Рассмотрите возможность просмотра параметров компилятора.
Прошло много времени с тех пор, как я работал на 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, но может помочь объяснить результаты, которые вы видели.