Числовая точность в Фортране 95:
У меня есть следующий код Fortran:
Program Strange
Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209;
Real(Kind=8)::Pi2=3.1415926535897932384626433832795028841971693993751058209_8;
Print*, "Pi1=", Pi1;
Print*, "Pi2=", Pi2;
End Program Strange
Я компилирую с gfortran, и вывод:
Pi1= 3.1415927410125732
Pi2= 3.1415926535897931
Конечно, второе правильно, но так ли это? Кажется, что Pi1 вводится в память как число с одинарной точностью, а затем помещается в слот памяти двойной точности. Но это кажется мне ошибкой. Я прав?
2 ответа
Я немного знаю Фортран! @ Ответ Дугала верен, хотя фрагмент, из которого он цитирует, - нет, встраивая письмо d
в настоящую буквальную константу не требуется (начиная с Фортрана 90), действительно многие программисты на Фортране теперь считают такой подход архаичным. Фрагмент также вводит в заблуждение, советуя использовать 3.1415926535d+0
чтобы инициализировать 64-битное значение с плавающей точкой для pi, он не устанавливает достаточное количество цифр для их правильных значений.
Заявление:
Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209
определяет Pi1
быть реальной переменной вида 8. Буквальная реальная ценность 3.1415926535897932384626433832795028841971693993751058209
однако это реальное значение типа по умолчанию, наиболее вероятно, что оно будет 4-байтовым вещественным значением в большинстве современных компиляторов. Кажется, это объясняет ваш вывод, но проверьте документацию.
С другой стороны, буквальная реальная стоимость Pi2=3.1415926535897932384626433832795028841971693993751058209_8
согласно суффиксу спецификации вида объявляется с типом =8, который совпадает с типом переменной, которой он назначен.
Еще три пункта:
1) Не попадайтесь в ловушку, думая, что kind=8
означает то же самое, что и 64-bit floating-point number
или же double
, Для многих компиляторов это так, для некоторых - нет. Добрые числа не переносимы между реализациями на Фортране. Согласно стандарту они являются произвольными натуральными числами. Лучше, с современным компилятором, было бы использовать предопределенные константы из встроенного модуля iso_fortran_env
например,
use, intrinsic :: iso_fortran_env
...
real(real64) :: pi = 3.14159265358979323846264338_real64
Существуют и другие переносимые подходы к настройке типов переменных с использованием таких функций, как selected_real_kind
,
2) Так как значение pi
вряд ли изменится во время выполнения вашей программы, возможно, вы захотите сделать ее параметром таким образом:
real(real64), parameter :: pi = 3.14159265358979323846264338_real64
3) Нет необходимости (или обычно) заканчивать утверждения на Фортране знаком ';' если вы не хотите иметь более одной инструкции в одной строке исходного файла.
Я действительно не знаю Фортран, но на этой странице написано:
Буква "d" должна быть встроена в литерал, в противном случае препроцессор компилятора округлит его до литерала Single Precision. Например, 3.1415926535 будет читаться как 3.141593, в то время как 3.1415926535d+0 будет сохранено с сохранением всех цифр. Буква "d" для чисел двойной точности имеет то же значение, что и "e" для чисел одинарной точности.
Так что, похоже, ваше предположение верно.