首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有/out编译器标志的Fortran精度默认值

带有/out编译器标志的Fortran精度默认值
EN

Stack Overflow用户
提问于 2018-06-18 18:38:39
回答 3查看 2.2K关注 0票数 5

在Fortran中,我对恒定数字的精确性有困难。

我是否需要将每一个0.1写成0.1d0才能实现双精度?我知道编译器有一个标记,例如gfortran中的-fdefault-real-8,它解决了这种问题。这会是一种便携可靠的方法吗?如何检查标志选项是否真正适用于我的代码?

我使用F2py在我的Python代码中调用Fortran代码,即使我给出了一个未指定的标志,它也不会报告错误,这就是我担心的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-06-19 02:04:45

你的问题的答案是:是的,你确实需要指出常数是双精度的。使用0.1是这个问题的一个常见例子,因为4字节和8字节表示是不同的.其他常量(如0.5),其中扩展的精度字节都为零,没有这个问题。

这是在F90的Fortran中引入的,并给许多遗留的FORTRAN代码的转换和重用带来了问题。在F90之前,双精度a= 0.1的结果可以使用实际的0.1或双0.1常数,尽管我使用的所有编译器都提供了一个双精度值。在用已发布的结果测试遗留代码时,这可能是不一致结果的常见来源。例子经常被报道,例如PI=3.141592654在本周的一个论坛上的代码中。

但是,使用0.1作为子例程参数总是会引起问题,因为这将作为一个真正的常量来传递。

因此,考虑到实际常量是如何处理的历史,您确实需要在需要时显式指定双精度常量。这不是一种用户友好的方法。

票数 0
EN

Stack Overflow用户

发布于 2018-06-18 19:44:12

在Fortran程序中,1.0始终是一个默认的实文本常量,而1.0d0总是一个双精度的文字常量。

然而,“双重精度”在不同的语境中意味着不同的事物。

在Fortran上下文中,“双重精度”指的是一种特定类型的实值,它比默认的实类具有更高的精度。在更一般的通信中,“双精度”通常被理解为一种特定的符合IEEE浮点规范的64位的真实类型。

gfortran的编译器标志-fdefault-real-8意味着默认的实数需要8个字节,并且很可能是编译器用来表示IEEE双精度的值。

因此,1.0是一个默认的实文本常量,而不是一个双精度的文字常量,但是缺省的实值可能恰好与IEEE的双精度相同。

this one这样的问题在文字常量中反映了精度的含义。如果有人问我关于像-fdefault-real-8这样的旗帜的建议,我会说要避免它们。

票数 6
EN

Stack Overflow用户

发布于 2018-06-18 22:29:42

此外,我认为,由于双重精度定义可能在不同平台和编译器之间发生变化,因此使用标准Fortran约定显式声明所需类型的常量是一种很好的做法,如下所示:

代码语言:javascript
复制
program test
    use, intrinsic :: iso_fortran_env, only: RK => real64
    implicit none
    write(*,"(*(g20.15))") "real64: ", 2._RK / 3._RK
    write(*,"(*(g20.15))") "double precision: ", 2.d0 / 3.d0
    write(*,"(*(g20.15))") "single precision: ", 2.e0 / 3.e0
end program test

使用gfortran编译此代码将提供:

代码语言:javascript
复制
$gfortran -std=gnu *.f95 -o main
$main
            real64: .666666666666667    
  double precision: .666666666666667    
  single precision: .666666686534882    

在这里,前两行(64位实类和双精度类的显式请求)的结果是相同的。但是,通常情况下,情况可能不是这样,双精度结果可能取决于编译器标志或硬件,而real64类型将始终符合64位真实类型计算,而不管默认的真实类型。

现在考虑另一种情况,一个人已经声明一个真正的变量是64位的,然而,数值计算是以32位的精度进行的,

代码语言:javascript
复制
program test
    use, intrinsic :: iso_fortran_env, only: RK => real64
    implicit none
    real(RK) :: real_64
    real_64 = 2.e0 / 3.e0
    write(*,"(*(g30.15))") "32-bit accuracy is returned: ", real_64
    real_64 = 2._RK / 3._RK
    write(*,"(*(g30.15))") "64-bit accuracy is returned: ", real_64
end program test

它提供了以下输出,

代码语言:javascript
复制
$gfortran -std=gnu *.f95 -o main
$main
 32-bit accuracy is returned:          0.666666686534882    
 64-bit accuracy is returned:          0.666666666666667    

尽管变量被声明为real64,但第一行的结果仍然是错误的,因为它们不符合双精度类型(您希望的64位)。原因是,计算首先以文字常量的请求(默认为32位)精度完成,然后存储在64位变量real_64中,因此,从输出中的第二行的更准确的答案中得到一个不同的结果。

因此,底线信息是:使用“下划线”约定,显式声明Fortran中的文字常量的类型是一个好做法。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50915600

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档