Arrays 为什么这两个完全相同的计算在Fortran中使用gfortran得到不同的结果?
这是我运行此代码时得到的结果Arrays 为什么这两个完全相同的计算在Fortran中使用gfortran得到不同的结果?,arrays,floating-point,fortran,gfortran,floating-point-precision,Arrays,Floating Point,Fortran,Gfortran,Floating Point Precision,这是我运行此代码时得到的结果 real, dimension(3), parameter :: boxlen = [4.0, 5.0, 7.0] real, parameter :: mindist = 0.1 integer ::i write(*,"(A)") "Operation on array" print*, floor(boxlen/mindist) write(*,"(/A)") "Operation on individual elements" do i=1
real, dimension(3), parameter :: boxlen = [4.0, 5.0, 7.0]
real, parameter :: mindist = 0.1
integer ::i
write(*,"(A)") "Operation on array"
print*, floor(boxlen/mindist)
write(*,"(/A)") "Operation on individual elements"
do i=1,3
print*, i, floor(boxlen(i)/mindist)
enddo
有人能解释为什么这两种计算(一种使用数组运算,另一种使用单个元素运算)给出不同的结果吗?我认为它们应该是一样的。对于我来说,在x86_64-linux-gnu上使用GFortran 4.8.2我得到了
Operation on array
40 50 70
Operation on individual elements
1 39
2 49
3 69
阵列上的操作
40 50 70
对单个元素的操作
1 40
2 50
3 70
仔细观察我的水晶球,如果您使用32位x86,那么计算值存储到内存和打印的顺序可能会有所不同
另外,查看生成的中间代码,其中包含“-fdump tree original”,似乎对于数组操作,除法是在编译时完成的(因此,由于MPFR,至少应该正确舍入)。您使用的是哪个gfortran版本?它在gfortran 5.1上运行良好!你的编译选项是什么?使用
i=1;打印*,地板(boxlen(i)/心灵医生)-地板(boxlen(1)/心灵医生)
我得到了一个惊喜。gfortran 4.8.1就是这样。我使用的是GNU Fortran(GCC)4.10.0 20140629(实验版)[主干修订版212119]。我使用gfortran-Wall-std=f2008-O3编译,浮点除以0.1是不精确的,所以原则上两种结果都是可能的。考虑到明显相同的表述,我认为我们应该期待相同的结果,@YodeshYadav:我会避免使用equation.com构建。他们似乎有很多特定于方程式的bug,而且由于他们没有发布修改过的源代码(违反了许可证),如果它们碰巧击中了你,没有人可以帮助你调试它们。如果您需要替代方案,Mingw-w64和TDM版本似乎相当流行。我不知道他们是否有5.1版本,但除非你使用更深奥的OOP或coarray,否则你可能暂时可以用旧版本来管理。我使用的是64位intel处理器。@YogeshYadav:很好。您是否也在使用64位GFortran?例如,“gfortran-v”对目标显示了什么:?对于gfortran-v,它将mingw32作为目标。@janneb,在我看来,更改编译器是一个非常糟糕的建议,因为OP dos not like的行为完全是好的和标准的。浮点运算是不精确的,所以我们首先不应该期望得到40.0除以4.0除以1.0。因此,OP实际上需要改变对浮点运算和算法的思考方式,而不是编译器。@Wildcat:4.0/1.0等于40.0可能符合标准,但我怀疑大多数用户对实现的质量有更严格的要求。
Operation on array
40 50 70
Operation on individual elements
1 40
2 50
3 70