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?
没有必要为可精确表示的数字指定种类。所有不太大的整数都可以准确地表示为 IEEE 标准浮点数。因此,不需要像1.或 之类的常量3.。还有一半可以用二进制完全表示,因此1./2.可以正常工作。
对于不能完全表示的其他值,这是必要的,因为没有后缀,文字被视为默认类型(单精度)。在你的情况下3.3不能完全代表,你会得到不同的结果
write(*,*) 3.3, 3.3_rkind
3.29999995 3.2999999999999998
Run Code Online (Sandbox Code Playgroud)
让我们先看看测试 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)
它只是恰巧,1并1.都在你的数字模型,可转换确切地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] 尾数的其余部分”。