Есть ли лучшее назначение с двойной точностью в Fortran 90? - PullRequest
6 голосов
/ 27 мая 2011

В Fortran 90 (используя gfortran в Mac OS X), если я присваиваю значение переменной двойной точности без явного указания вида, точность не «принимает». Что я имею в виду, если я запускаю следующую программу:

program sample_dp

implicit none

integer, parameter :: sp = kind(1.0)
integer, parameter :: dp = kind(1.0d0)

real(sp) :: a = 0.
real(dp) :: b = 0., c = 0., d = 0.0_dp, e = 0_dp

! assign values
a = 0.12345678901234567890
b = 0.12345678901234567890
c = DBLE(0.12345678901234567890)
d = 0.12345678901234567890_dp

write(*,101) a, b, c, d
101 format(1x, 'Single precision: ',  T27, F17.15, / &
           1x, 'Double precisison: ', T27, F17.15, / &
           1x, 'Double precision (DBLE): ', T27, F17.15, / &
           1x, 'Double precision (_dp): ',  T27, F17.15)

end program

Я получаю результат:

Single precision:        0.123456791043282
Double precision:        0.123456791043282
Double precision (DBLE): 0.123456791043282
Double precision (_dp):  0.123456789012346

Результат с одинарной точностью начинает округляться с восьмым десятичным знаком, как и ожидалось, но только переменная двойной точности, которую я назначил явно с помощью _dp, сохраняет все 16 цифр точности. Это кажется странным, так как я ожидал (я относительно новичок в Фортране), что переменная двойной точности автоматически будет двойной точности. Есть ли лучший способ назначить переменные двойной точности, или я должен явно ввести их, как указано выше?

Ответы [ 2 ]

8 голосов
/ 27 мая 2011

Реальное, которое не помечено как двойная точность, будет считаться одинарной точностью.То, что через некоторое время вы присваиваете переменную двойной точности или конвертируете ее в двойную точность, это не означает, что значение «волшебным образом» будет двойной точности.Пока не видно, как будет использоваться это значение.

3 голосов
/ 06 марта 2017

Есть несколько вопросов, связывающих здесь, поэтому лучше изложить некоторые подробности с примерами, особенно для начинающих.

Как указал MRAB в своем правильном ответе, выражение всегда вычисляется без какого-либо контекста, поэтому

 0.12345678901234567890

- это плавающий литерал по умолчанию (одинарный), независимо от того, где он появляется. То же самое относится к числам с плавающей запятой в экспоненциальной форме

 0.12345678901234567890E0

это также число точности по умолчанию.

Если вы хотите использовать константу двойной точности, можно использовать D вместо E в приведенной выше форме. Даже если такая константа двойной точности назначена переменной точности по умолчанию, она сначала обрабатывается как число двойной точности, а затем преобразуется в точность по умолчанию.

То, как вы используете в своем вопросе (с использованием добрых обозначений и нескольких добрых констант), является более общим и более современным, но принцип тот же.

 0.12345678901234567890_sp

это число вида sp и

 0.12345678901234567890_dp

- это число типа dp, и не имеет значения, где они появляются.

Как показывает ваш пример, речь идет не только о назначении. В строке

 c = DBLE(0.12345678901234567890)

первое число 0.12345678901234567890 - точность по умолчанию. Затем он преобразуется в удвоенную точность на DBLE, но это делается после того, как некоторые цифры уже потеряны. Затем этот новый номер двойной точности присваивается c.

...