Фортран: наибольшее и наименьшее целое число
Фортран для меня совершенно новый, кто-нибудь может мне помочь решить следующую проблему? Я хочу узнать все целые числа вида, а также самое большое и наименьшее значение для каждого вида на моем компьютере. У меня есть код, указанный ниже:
program intkind
implicit none
integer :: n=1
integer :: integer_range =1
do while(integer_range /= -1)
print*, "kind_number ", selected_int_kind(n)
call rang(integer_range)
n = n *2
integer_range = selected_int_kind(n)
end do
contains
subroutine rang(largest)
integer largest
print*, huge(largest)
end subroutine
end
Целые добрые числа, которые я получаю: 1,2,4,8.
Почему каждое наибольшее целое число для каждого вида одинаково:
2147483647
? И есть ли встроенная функция для наименьшего целого числа?Как мне сохранить целочисленное доброе число, когда подпрограмма
rang
называется? Я думаю, что это ключ к наибольшему целому числу.
2 ответа
Ваша подпрограмма:
subroutine rang(largest)
integer :: largest
print *, huge(largest)
end subroutine
принимает в качестве входных данных целое число размера по умолчанию и печатает максимально возможное значение, которое поместится в это целое число размера по умолчанию. Он всегда будет возвращать огромный (по умолчанию целое число), который в большинстве систем огромный (4-байтовое целое) или 2147483647. huge
учитывает только тип переменной; это никак не интерпретирует переменную. Единственный способ сделать то, что вы пытаетесь сделать выше, это с помощью параметризованных производных типов, которые являются достаточно новыми, поэтому его поддержка в компиляторах все еще немного затруднена.
Если вы хотите взглянуть на диапазоны различных типов INTEGER, вам придется использовать разные переменные:
program integerkinds
use iso_fortran_env
implicit none
integer :: i
integer(kind=int8) :: i8
integer(kind=int16) :: i16
integer(kind=int32) :: i32
integer(kind=int64) :: i64
integer(kind=selected_int_kind(6)) :: j6
integer(kind=selected_int_kind(15)):: j15
print *,'Default:'
print *, huge(i)
print *,'Int8:'
print *, huge(i8)
print *,'Int16:'
print *, huge(i16)
print *,'Int32:'
print *, huge(i32)
print *,'Int64:'
print *, huge(i64)
print *,''
print *,'Selected Integer Kind 6:'
print *, huge(j6)
print *,'Selected Integer Kind 15:'
print *, huge(j15)
end program integerkinds
Бег дает:
$ ./intkinds
Default:
2147483647
Int8:
127
Int16:
32767
Int32:
2147483647
Int64:
9223372036854775807
Selected Integer Kind 6:
2147483647
Selected Integer Kind 15:
9223372036854775807
Чисто как дополнение или альтернативная перспектива, переменные Фортрана определяются в терминах количества байтов памяти, выделенных для переменной. Действительно, все сопоставимые компиляторы определяют переменные в терминах выделенных байтов, иначе системе было бы очень трудно распределить / сохранить в памяти, и очень очень трудно выполнить арифметику и т.д. без таковой.
Для некоторых, таких как я, легче увидеть, что происходит, используя немного более старую нотацию (а не "добрую конфузию"). В частности, очень многие компиляторы обеспечивают прямое соответствие 1:1 между Kind и bytes/var, что затем делает вычисление наибольшего / наименьшего целого числа довольно простым (некоторые компиляторы используют нелинейное или непрямое соответствие). Хотя обязательно обратите внимание на помощь в переносимости в конце. Например,
Integer(1) :: Int1 ! corresponds to a 1 byte integer
Integer(2) :: Int1 ! corresponds to a 2 byte integer
Integer(4) :: Int1 ! corresponds to a 4 byte integer
Integer(8) :: Int1 ! corresponds to an 8 byte integer
Аналогичная запись применяется к другим типам Фортрана (Реальный, Логический и т. Д.). Все типы переменных имеют количество байтов по умолчанию, если "размер" не указан.
Максимальное количество байтов для конкретного типа также зависит от компилятора и системы (например, Integer(16) доступен не во всех системах и т. Д.).
Байт составляет 8 бит, поэтому один байт должен быть в состоянии вместить наибольшее значение 2^8 = 256 при нумерации от 1 или = 255 при запуске с 0.
Однако в Фортране (почти все) числовые переменные "подписаны". Это означает, что где-то в битовом представлении требуется один бит, чтобы отслеживать, является ли число числом + ve или числом -ve. Таким образом, в этом примере максимальное значение будет равно 2^7, поскольку один бит "потерян / зарезервирован" для информации "знака". Таким образом, возможные значения для 1-байтового целого числа со знаком составляют -127:+128 (обратите внимание, что сумма Abs(пределов) равна 255, поскольку "0" занимает одно место, в сумме 256 "вещей", как и должно быть "). быть).
Аналогичное правило применяется ко всем таким переменным, причем просто показатель степени "n" в 2^n меняется в зависимости от количества байтов. Например, переменная Integer(8) имеет 8 байтов или 64 бита, причем 1 бит потерян / зарезервирован для информации знака, поэтому наибольшее возможное значение будет 2^63 = 9223372036854775808, если нумерация от 1 или = 4611686018427387904 при запуске от 0.
Стандартная модель данных Integer будет обобщена как:
IntNum = s * Sum[ w(k) * 2 ^ (k-1), k=1:(NumBytes*8)-1],
где s = "знак" (+/-1), w(k) равно 1 или 0 для значения k-го бита.
Не нужно использовать явные числа или переменные env в объявлениях типов; Определяемые пользователем константы времени компиляции (т.е. параметры) разрешены. Например
Integer, Parameter :: DP = Kind(1.0d0) ! a standard Double Precision/8-byte declaration
Integer, Parameter :: I4B = 4 ! NOTICE, here the "Integer" bit has not been explicitly "sized", so defaults to "Integer(4)"
!
Real(DP) :: ADoublePrecReal ! an 8-byte Real (approx 15 decimal places with exp +/- approx 300, see Real data model)
!
Integer(I4B) :: AStandardInt ! a 4-byte integer.
Поскольку оператор Parameter может находиться в другом модуле, доступном через Use и т. Д., Очень просто перекомпилировать большой сложный код для альтернативных определений требуемой "точности". Например, если DP отредактирован в Kind(1.0), то везде, где применяется это объявление, оно становится "реальной точностью".
Встроенные в Фортран функции Huge(), Tiny() и т. Д. Помогают определить, что возможно в данной системе.
Гораздо больше можно сделать с помощью "битовых" встроенных функций Фортрана и других инструментов / методов.