Фортран: наибольшее и наименьшее целое число - PullRequest
11 голосов
/ 05 марта 2012

Фортран для меня совершенно новый, кто-нибудь может мне помочь решить следующую проблему?Я хочу узнать все целые числа вида, а также самое большое и наименьшее значение для каждого вида на моем компьютере.У меня есть код, указанный ниже:

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.

  1. Почему каждое наибольшее целое число длякаждый добрый номер одинаков: 2147483647?И есть ли встроенная функция для наименьшего целого числа?

  2. Как мне сохранить целочисленный номер вида при вызове подпрограммы rang?Я думаю, что это ключ к наибольшему целому числу.

Ответы [ 2 ]

16 голосов
/ 05 марта 2012

Ваша подпрограмма:

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
0 голосов
/ 13 августа 2014

Чисто как дополнение или альтернативная перспектива, переменные Фортрана определяются в терминах количества байтов памяти, выделенных для переменной. Действительно, все сопоставимые компиляторы определяют переменные в терминах выделенных байтов, иначе системе было бы очень трудно распределить / сохранить в памяти и очень и очень трудно выполнить арифметику и т. Д. Без них.

Для некоторых, таких как я, легче увидеть, что происходит, используя немного более старую нотацию (нежели «добрую конфузию»). В частности, очень многие компиляторы обеспечивают прямое соответствие 1: 1 между типом и байтами / 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

Аналогичные обозначения применяются к другим типам Фортрана (Реальный, Логический и т. Д.) Всем типам переменных присваивается число байтов по умолчанию, если «размер» не указан.

Максимальное количество байтов для конкретного типа также зависит от компилятора и системы (например, целое число (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.

Стандартная целочисленная модель данных будет обобщена как:

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), то везде, где применяется это объявление, оно становится «одинарной точностью». Real.

Встроенные в Фортран функции Huge (), Tiny () и т. Д. Помогают определить, что возможно в данной системе.

Многое можно сделать с помощью "битовых" встроенных функций Фортрана и других инструментов / методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...