Ale*_*o B 5 math floating-point
如何使用不同的编译器以及可能还有不同的计算机使用浮点算法获得相同的结果?
这是p.f90
program fl
implicit none
real(kind=8) :: a
a=9d0/10d0
write(*,*) a
end program
Run Code Online (Sandbox Code Playgroud)
使用gfortran -op p.f90,我得到0.90000000000000002
使用ifort -g -op p.f90,我得到0.900000000000000
有没有办法实现一致性?小东西传播并变得更大.
最好的问候亚历山德罗
我们将在下面讨论浮点运算,但让我首先处理你的误解.在write语句中使用列表定向格式意味着编译器选择写出变量的格式是编译器的选择; 这不是语言标准的强制要求.您对第二个的*使用write(*,*)告诉编译器根据需要写出变量的值.所以你所拥有的并不是算术存在问题的证据,而是gfortran和之间存在差异ifort.如果我修改你的写声明
write(*,'(f21.18)') a
Run Code Online (Sandbox Code Playgroud)
然后我的英特尔Fortran程序写道
0.900000000000000022
Run Code Online (Sandbox Code Playgroud)
到控制台.
因为不熟悉浮点运算的细节而产生的问题很多,所以我不打算写一篇论文,只是一些与你的问题相关的观察.
IEEE-754 64位浮点数(可能与声明相同real(kind=8))仅提供大约16位有用信息的十进制数字.实际上,由于它们是二进制的,并且在一个基数和另一个基数中的数字之间没有简单的对应关系,它实际上是15.95个十进制数字,并且许多用户将这个数字向下舍入并且在浮动之后的第15个有效数字之后从不查看任何内容点数的十进制表示.因此,无论ifort和gfortran与它们的尾随误导你2秒.
IEEE-754不仅定义了fp数的格式,还定义了舍入和算术运算的一些规则.一个精心编写的程序,它只使用那些算术运算(我认为也指定了平方根)并且负责舍入模式和舍入运算应该在两个不同的处理器上产生相同的结果.当然,没有多少有用的数值程序仅限于基本的算术运算.
由于2003标准Fortran包含一个内部模块ieee_arithmetic,它使程序员可以直接访问运行它的硬件的基础IEEE-754功能 - 但请注意,它并不要求硬件具有任何此类功能.使用ieee_arithmetic和另一个叫做内在的模块ieee_exceptions,你应该,如果你的硬件提供了必要的支持,能写出这下这两个编译程序gfortran和ifort执行时和产生,相同的结果,每一个FP号码的最后一位.
您还需要熟悉您正在使用的编译器的优化选项和数值算术选项.大多数编译器都有一个选项,其含义是sacrifice IEEE compliance for speed(ifort我认为是fp-model).一般来说,遵守IEEE-754操作会降低程序的速度.
| 归档时间: |
|
| 查看次数: |
1560 次 |
| 最近记录: |