Fortran: наибольшее и наименьшее целое число
Fortran для меня совершенно новый, может ли кто-нибудь помочь мне решить проблему? Я хочу узнать все числа чисел целого числа и наибольшее и наименьшее значение для каждого типа номера на моем компьютере. У меня есть код, указанный ниже:
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
? Я думаю, что это ключ к наибольшему целому числу.
Ответы
Ответ 1
Ваша подпрограмма:
subroutine rang(largest)
integer :: largest
print *, huge(largest)
end subroutine
принимает в качестве значения целочисленное значение по умолчанию и выводит наибольшее возможное значение, которое будет соответствовать целому числу по умолчанию. Он всегда будет возвращать огромное (по умолчанию целое число), которое на большинстве систем огромно (4-байтовое целое) или 2147483647. huge
учитывает только тип переменной; он никак не интерпретирует переменную. Единственный способ, которым вы могли бы сделать то, что вы пытаетесь сделать выше, - это параметризованные производные типы, которые являются достаточно новыми, которые поддерживают его в компиляторах, все еще немного пятнистые.
Если вы хотите взглянуть на диапазоны разных KIND для 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
Ответ 2
Чисто в качестве дополнения или альтернативной перспективы переменные Fortran определяются в терминах количества байтов памяти, выделенных для var. Действительно, все сопоставимые компиляторы определяют vars в терминах выделенных байтов, иначе было бы очень сложно для системы выделять/хранить в памяти, и очень сложно выполнить арифметику и т.д. Без нее.
Для некоторых, как и я, легче понять, что происходит, используя немного более старую нотацию (а не "рода konfusion". В частности, очень многие компиляторы обеспечивают прямое соответствие 1:1 между Kind и байтами /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
Аналогичное обозначение относится к другим типам Fortran (Real, Logical и т.д.). Все типы var имеют заданное по умолчанию количество байтов, если "размер" не указан.
Максимальное количество байтов для определенного типа также зависит от компилятора и системы (например, Integer (16) недоступен для всех систем и т.д.).
Байт имеет 8 бит, поэтому один байт должен иметь возможность разместить наибольшее значение 2 ^ 8 = 256, если нумерация от 1 или 255 начинается с 0.
Однако в Fortran (почти все) числовые вары "подписаны". Это означает, что где-то в битовом представлении требуется один бит для отслеживания, является ли это число + ve или число -ve. Таким образом, в этом примере max будет равен 2 ^ 7, поскольку один бит "потерян/зарезервирован" для "знаковой" информации. Таким образом, значения, доступные для подписанного 1-байтового целого числа, равны -127: +128 (обратите внимание на сумму Abs (пределы) до 255, так как "0" занимает одно место, всего 256 "вещей", так как это должно быть).
Аналогичное правило применяется для всех таких vars, просто с показателем "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 vars; разрешены определенные пользователем константы времени компиляции (т.е. параметры). Например
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), то везде, где применяется эта декларация, становится "единственной точностью" Real.
Встроенные функции Fortran Huge(), Tiny() и т.д. помогают определить, что возможно в данной системе.
Гораздо больше может быть выполнено с помощью "бит-бит" Fortran и других инструментов/методов.