9

在 Fortran 90(在 Mac OS X 上使用 gfortran)中,如果我将一个值分配给一个双精度变量而没有明确地附加一种类型,则精度不会“采用”。我的意思是,如果我运行以下程序:

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

单精度结果按预期从第 8 位小数开始四舍五入,但只有我用 _dp 显式分配的双精度变量保持所有 16 位精度。这似乎很奇怪,正如我所期望的(我对 Fortran 比较陌生)双精度变量将自动是双精度的。有没有更好的方法来分配双精度变量,还是我必须像上面那样显式键入它们?

4

2 回答 2

11

未标记为双精度的实数将被假定为单精度。仅仅因为稍后您将其分配给双精度变量,或将其转换为双精度,这并不意味着该值将“神奇地”成为双精度。它不会向前看如何使用该值。

于 2011-05-26T23:04:27.473 回答
9

此处链接了几个问题,因此最好通过示例更明确地说明一些细节,尤其是对于初学者。

正如 MRAB 在他的正确答案中所说,表达式总是在没有任何上下文的情况下被评估,所以

 0.12345678901234567890

是一个默认(单)精度浮动文字,无论它出现在哪里。这同样适用于指数形式的浮点数

 0.12345678901234567890E0

它也是一个默认的精度数。

如果想使用双精度常量,可以使用上述形式D来代替。E即使将这样的双精度常量分配给默认精度变量,它也会首先被视为双精度数,然后再转换为默认精度。

您在问题中使用的方式(使用种类符号和几个种类常量)更通用,更现代,但原理是相同的。

 0.12345678901234567890_sp

是一些种类sp

 0.12345678901234567890_dp

是多种类型dp,它们出现在哪里并不重要。

正如您的示例所示,这不仅与分配有关。在行

 c = DBLE(0.12345678901234567890)

首先数字0.12345678901234567890是默认精度。然后通过 将其转换为双精度DBLE,但这是在一些数字已经丢失之后完成的。然后将这个新的双精度数分配给c

于 2017-03-06T09:42:17.480 回答