在现代 Fortran 中是否有必要将 _kind 附加到数字文字?

Is it necessary to append _kind to number literals in modern Fortran?

这可能是个愚蠢的问题,但在最近的一些测试后我有点困惑。我一直认为 Fortran 处理实数的方式如下(现代声明):

program testReal

  implicit none

  integer, parameter :: rkind=8

  real(kind=rkind) :: a,b,c

  // Test 1
  a = 1
  b = 1.
  c = 1._rkind
  write(*,"(2(1xES23.15))") a, b, c

  // Test 2
  a = 1/2
  b = 1/2.
  c = 1./2.
  write(*,"(2(1xES23.15))") a, b, c

  // Test 3
  a = 3.3
  b = 1 * a
  c = 1. * a
  write(*,"(2(1xES23.15))") a, b, c

end program testReal

除了Test 2 - a之外,一切都一样。我一直以为我必须把例如1._rkind, 0.5_rkind, etc. 在每个实数之后以确保用零填充其余的尾数?

这只是纯粹的运气还是真的不再需要附加 _rkind

可以精确表示的数字不需要指定类型。所有不太大的整数都可以精确表示为 IEEE 标准浮点数。因此,没有必要像 1.3. 这样的常量。还有一半可以用二进制表示,所以 1./2. 可以正常工作。

对于不能准确表示的其他值是必需的,因为没有后缀,文字被视为默认种类(单精度)。在你的情况下 3.3 不能完全表示,你会得到不同的结果

write(*,*) 3.3, 3.3_rkind

3.29999995       3.2999999999999998  

我们先来看测试1。这里的11.1._rkind是常量。 1 是默认种类的整数; 1. 是默认种类的实数; 1._rkind 是种类 rkind 的实数(可能与默认种类相同)。这些都是不同的东西。

但是,在这种情况下,作业中发生的事情是关键。由于 abc 都是实数 rkind 相应的 right-hand 边都转换为实数 rkind (假设这种类型比默认类型具有更高的精度)。转换等同于

a = REAL(1, rkind)
b = REAL(1., rkind)
c = 1._rkind

碰巧 11. 在您的数字模型中都可以完全转换为 1._rkind.

我不会涉及测试 2,因为差异是 "obvious"。

在测试 3 中,我们有文字常量 3.3,它是默认类型的实数。再次

a = REAL(3.3, rkind)
b = REAL(1, rkind)*REAL(3.3, rkind)
c = REAL(1., rkind)*REAL(3.3, rkind)

由于转化发生的地点和方式。从这里你可以看出结果是相当相同的,并且算术是真实的 rkind.

您会注意到不同之处

a = 3.3
b = 3.3_rkind

因为(数学)实数 3.3 在您的数值模型中不能准确表示。并且近似值将与默认种类和种类 rkind.

的实数不同

特别是"fill[ing] the rest of the mantissa with zeros".

不用担心