Fortran 赋值后的实值与实表达式不同
我正在翻译Fortran的代码。 我在作业中有一种奇怪的行为。我知道添加代码会非常有帮助,但我无法添加准确的代码(我未获得授权),而且我没有成功地复制它 行如下(qk是预定义的,而qk1不是): 我将这些值打印出来:Fortran 赋值后的实值与实表达式不同,fortran,variable-assignment,Fortran,Variable Assignment,我正在翻译Fortran的代码。 我在作业中有一种奇怪的行为。我知道添加代码会非常有帮助,但我无法添加准确的代码(我未获得授权),而且我没有成功地复制它 行如下(qk是预定义的,而qk1不是): 我将这些值打印出来: qk 21909779.000000000 qk1 6.44842193E+32 qk 21909779.000000000 qk1 21909780.0 关键是我希望得到qk1等于qk。。。为什么它们不同?
qk 21909779.000000000
qk1 6.44842193E+32
qk 21909779.000000000
qk1 21909780.0
关键是我希望得到qk1等于qk。。。为什么它们不同?
当我尝试复制它时,很明显我得到了相同的值
因为我没有添加代码,所以我不希望得到准确的答案。。。有人知道要检查什么吗?原因是,如注释所示,qk为单精度,qk1为双精度,并且在所需的值处,单精度实数之间的间距为2:
Program one_out
Use, Intrinsic :: iso_fortran_env, Only : real32, real64
Implicit None
Real( real64 ) :: qk64
Real( real32 ) :: qk32
qk64 = 21909779.0_real64
qk32 = qk64
Write( *, * ) 'qk64 = ', qk64
Write( *, * ) 'qk32 = ', qk32
Write( *, * ) '64 spacing ', Spacing( qk64 )
Write( *, * ) '32 spacing ', Spacing( qk32 )
End Program one_out
ian@eris:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 one_out.f90
one_out.f90:11:9:
qk32 = qk64
1
Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1) [-Wconversion]
ian@eris:~/work/stack$ ./a.out
qk64 = 21909779.000000000
qk32 = 21909780.0
64 spacing 3.7252902984619141E-009
32 spacing 2.00000000
这里最重要的一课总是,总是使用隐式无-第二课是编译器警告很有用,打开它们并找出它们的含义 原因是,如注释所示,qk为单精度,qk1为双精度,且在所需值下,单精度实数之间的间距为2:
Program one_out
Use, Intrinsic :: iso_fortran_env, Only : real32, real64
Implicit None
Real( real64 ) :: qk64
Real( real32 ) :: qk32
qk64 = 21909779.0_real64
qk32 = qk64
Write( *, * ) 'qk64 = ', qk64
Write( *, * ) 'qk32 = ', qk32
Write( *, * ) '64 spacing ', Spacing( qk64 )
Write( *, * ) '32 spacing ', Spacing( qk32 )
End Program one_out
ian@eris:~/work/stack$ gfortran -Wall -Wextra -fcheck=all -std=f2008 one_out.f90
one_out.f90:11:9:
qk32 = qk64
1
Warning: Possible change of value in conversion from REAL(8) to REAL(4) at (1) [-Wconversion]
ian@eris:~/work/stack$ ./a.out
qk64 = 21909779.000000000
qk32 = 21909780.0
64 spacing 3.7252902984619141E-009
32 spacing 2.00000000
这里最重要的一课总是,总是使用隐式无-第二课是编译器警告很有用,打开它们并找出它们的含义 qk和qk1是否定义为完全相同的类型和精度?小数点0的数量可能表示精度的差异,可能不相关,但显示的第一行会导致打印名为
qt
的变量值。我一直怀疑,在向SO发布代码时可能出现的粗心打字错误是由于编码粗心造成的……因此qk和qk1的数据类型(实精度与双精度)之间可能存在差异,但为了能够说出这一点,加上一个能说明你的问题的a。现在没有时间检查,但你已经接近“单精度”real可以提供的最大sig数字,我的怀疑是,由于这一点,你不能准确地表示数字,因此你得到了最接近的近似值,即1。请参阅和,以获取类似的信息。您的编译器试图为您修复错误,并使用了不同的精度。看看维基百科关于“单精度浮点格式”和“双精度浮点格式”的文章,注意IEEE 754是如何定义数字表示的。这可能有助于理解您选择的精度以及转换背后的限制qk和qk1是否定义为完全相同的类型和精度?小数点0的数量可能表示精度的差异,可能不相关,但显示的第一行会导致打印名为qt
的变量值。我一直怀疑,在向SO发布代码时可能出现的粗心打字错误是由于编码粗心造成的……因此qk和qk1的数据类型(实精度与双精度)之间可能存在差异,但为了能够说出这一点,加上一个能说明你的问题的a。现在没有时间检查,但你已经接近“单精度”real可以提供的最大sig数字,我的怀疑是,由于这一点,你不能准确地表示数字,因此你得到了最接近的近似值,即1。请参阅和,以获取类似的信息。您的编译器试图为您修复错误,并使用了不同的精度。看看维基百科关于“单精度浮点格式”和“双精度浮点格式”的文章,注意IEEE 754是如何定义数字表示的。这可能有助于理解你选择的精确度和转换背后的局限性。我想知道,在提问者的层面上,关于“间隔”是什么(或者为什么在这种情况下它很重要)的解释/链接是否会有帮助?好的-一天剩下的大部分时间都要开会,但可以,或者自己编辑答案,我可能会这样写:“不严格地说,值21909779落在附近可表示数字之间的间隙中。这个间隙就是所指的间距:在21909778和21909780之间的间距为2时,不可能精确指定值21909779”。但如果没有一个像样的链接,那就有点垃圾了。我想知道,在提问者的层面上,解释一下“间隔”是什么(或者为什么在这种情况下它很重要)是否会有帮助?好吧,一天剩下的大部分时间都在开会,但是可以,或者自己编辑答案,我可能会这样写“不严格地说,值21909779落在附近可表示数字之间的间隙中。这个间隙就是所指的间距:在21909778和21909780之间的间距为2时,不可能精确地指定值21909779“。但如果没有合适的链接,这有点垃圾。