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

Flo*_*nig 3 standards fortran gfortran

这可能是一个愚蠢的问题,但经过最近的一些测试,我有点困惑。我一直认为 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
Run Code Online (Sandbox Code Playgroud)

除了Test 2 - a一切都评估相同。我一直认为我必须1._rkind, 0.5_rkind, etc.在每个实数之后加上例如,以确保用零填充尾数的其余部分?

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

Vla*_*r F 5

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

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

write(*,*) 3.3, 3.3_rkind

3.29999995       3.2999999999999998  
Run Code Online (Sandbox Code Playgroud)

  • 不在乎名声。只需将一个答案标记为已接受。当你成为 sble 后,不要考虑声誉。我认为 francescalus 的回答不包含任何细节。 (2认同)

fra*_*lus 5

让我们先看看测试 1。这里1,1.1._rkind是文字常量。 1是一个默认类型的整数;1.是默认类型的实数;1._rkind是一种实数rkind(可能与默认类型相同)。这些都是不同的东西。

但是,在这种情况下,分配中发生的事情是关键。As a,b并且c都是种类rkind的实数,相应的右侧都被转换为种类的实数rkind(假设这样的种类比默认种类具有更高的精度)。转换相当于

a = REAL(1, rkind)
b = REAL(1., rkind)
c = 1._rkind
Run Code Online (Sandbox Code Playgroud)

它只是恰巧,11.都在你的数字模型,可转换确切地1._rkind

我不会涉及测试 2,因为差异是“明显的”。

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

a = REAL(3.3, rkind)
b = REAL(1, rkind)*REAL(3.3, rkind)
c = REAL(1., rkind)*REAL(3.3, rkind)
Run Code Online (Sandbox Code Playgroud)

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

你会注意到的是不同

a = 3.3
b = 3.3_rkind
Run Code Online (Sandbox Code Playgroud)

因为(数学)实数 3.3 在您的数值模型中不能完全表示。并且近似值将与 real 的 default kind 和 kind 不同rkind

特别是,无需担心“用零填充 [ing] 尾数的其余部分”。