Числовая точность в Фортране 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" для чисел одинарной точности.

Так что, похоже, ваше предположение верно.

Другие вопросы по тегам