Я сделаю ссылку на эту просветляющую статью , написанную недавно @SteveLionel, и попытаюсь охватить некоторые детали, которых пока нет в других ответах:
- Синтаксис, показанный в
integer*n
или real*n
, был распространенным расширением, предоставленным компиляторами давным-давно, когда разные компьютерные архитектуры начали иметь разные конструкции для формата целых и действительных значений в памяти, где n
было размер в байтах сохраненного значения. Однако это ничего не говорит о диапазоне или точности этих значений: например, разные реализации 16-битного целого числа могут предоставлять разные диапазоны и предельные значения.
Размеры регистров могут быть 8, 12, 16, 30, 32, 36, 48, 60 или 64 бит, некоторые машины CDC имели целые числа с одним дополнением (допускается минус ноль для целого числа!), Строка PDP-11 имела несколько разных форматов с плавающей запятой в зависимости от серии, IBM 360/370 имела «шестнадцатеричную нормализацию» для своей плавающей запятой и т. д. [...] Эти расширения были настолько популярны, что многие программисты думали (и даже сегодня многие думают), что этот синтаксис стандартный фортран; это не так
Когда вышел Fortran 90, в язык были добавлены параметры kind
, а также встроенные функции запроса (особенно kind
, selected_int_kind
и selected_real_kind
, но также и другие, такие как precision
, digits
, epsilon
...), чтобы помочь программисту определить минимальные требования для точности и диапазона числовых типов (тем не менее, никаких официальных упоминаний о модели хранения или байтах). Синтаксис integer(kind=n)
или даже integer(n)
, где n
- это постоянное значение, соответствующее виду целого числа, поддерживаемого компилятором. Для литеральных констант синтаксис 12_n
или 3.4e-2_n
.
Преимущество этого решения состояло в том, что Fortran не делал (и до сих пор не делает) никаких предположений о деталях реализации типов данных, кроме результатов функций запроса, используемых для выбора типа, поэтому код параметризовано решаемой проблемой, а не языком или оборудованием. Гоча, как сказано в других ответах, каждый компилятор может выбирать свои добрые числа, таким образом предполагая, что магическое число типа integer(4)
не является переносимым.
- Также в Fortran 90 появилась концепция видов по умолчанию , то есть то, что вы получаете, когда вы не указываете вид.
Виды по умолчанию зависели от реализации, хотя вплоть до Fortran 2008 компилятор должен был поддерживать только один целочисленный вид и два вещественных вида. (Это все еще верно в Fortran 2018, но есть дополнительное требование, чтобы по крайней мере один целочисленный вид поддерживал 18 десятичных цифр.) Если вы пишете константный литерал без спецификатора вида, вы получаете вид по умолчанию.
- С Fortran 2003 и включенным встроенным модулем
ieee_arithmetic
вы можете запросить и выбрать реальный тип с возможностями IEEE с плавающей запятой, если это возможно.
Существуют архитектуры, в которых доступны как плавающие типы IEEE, так и не-IEEE, такие как HP (ранее Compaq или ранее DEC) Alpha. В этом случае вы можете использовать IEEE_SELECTED_REAL_KIND из встроенного модуля IEEE_ARITHMETIC для получения плавающего вида IEEE. А что, если нет поддерживаемого вида, отвечающего требованиям? В этом случае встроенные функции возвращают отрицательное число, которое (обычно в зависимости от контекста) вызывает ошибку времени компиляции.
- Наконец, в Fortran 2003 появился встроенный модуль
iso_fortran_env
, который имел функции для запроса размера хранилища типов, реализованных компилятором, с такими встроенными функциями, как numeric_storage_size
и bit_size
. Еще одним дополнением к редакции Fortran 2003 был встроенный модуль iso_c_binding
, который предоставлял значения параметров вида, чтобы гарантировать совместимость с типами C в отношении хранения, точности и диапазона.
Внутренний модуль ISO_C_BINDING объявляет константы для типов Fortran, которые совместимы с типами C, например C_FLOAT и C_INT.Используйте их, если вы объявляете переменные и интерфейсы, совместимые с C.
В качестве последнего замечания я упомяну недавний стандарт Fortran 2008, который расширил встроенный модуль
iso_fortran_env
для включения именованных констант
int8
,
int16
,
int32
m
int64
,
real32
,
real64
и
real128
, значения которых соответствуют видам целых и вещественных типов, которые занимают указанное количество битов.Дело в том, что эти константы
гарантируют только размер хранилища , а не точность или диапазон.Используйте их только тогда, когда это именно то, что вам нужно.
На мой взгляд, это немного лучше, чем старое расширение * n, так как оно говорит вам, что тип подходит для такого количества бит, но больше ничего об этом.Например, есть один компилятор, в котором REAL128 хранится в 128 битах, но на самом деле это 80-битная реальная «расширенная точность», используемая в старых регистрах стека с плавающей запятой x86.Если вы используете их, вы можете подумать, что используете переносную функцию, но на самом деле это не так, и вас могут укусить, когда у того, кого вы получаете, нет необходимых вам возможностей.