首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >以gfortran为单位

以gfortran为单位
EN

Stack Overflow用户
提问于 2015-09-29 18:58:59
回答 2查看 1.8K关注 0票数 8

有什么办法可以迫使gfortran的地下水流冲至零?

我不敢相信这是第一次有人问这个问题,但我什么都找不到。如果这是重复的话。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-09-30 02:58:14

您可以通过支持Fortran 2003 IEEE模块的最新版本的gfortran来实现这一点。该标准定义了两种底流模式--渐进模式和突变模式。突变是您想要的,它将下流设置为0,并发出下流浮点异常信号。您可以使用函数ieee_support_underflow_control(X)测试对控制下流模式的支持,该函数测试实际X是哪种类型的下溢控制,如果支持它,则返回逻辑真。如果支持,则可以通过call ieee_set_underflow_mode(.false.)设置突然下流模式。

下面是一个测试程序,您可以使用它来测试底流控制对默认的真实类型的支持:

代码语言:javascript
复制
program test
  use, intrinsic :: ieee_arithmetic
  use, intrinsic :: iso_fortran_env, only: compiler_version, compiler_options
  implicit none
  logical :: underflow_support, gradual, underflow
  real :: fptest
  integer :: i

  print '(4a)',  'This file was compiled by ', &
       compiler_version(), ' using the options ', &
       compiler_options()
  fptest = 0.0
  underflow_support = ieee_support_underflow_control(fptest)
  if (underflow_support) then
     print *,'Underflow control supported for the default real kind'
  else
     stop 'no underflow control support'
  end if

  call ieee_set_underflow_mode(.false.)
  call ieee_get_underflow_mode(gradual)
  if (.not.gradual) then 
     print *,'Able to set abrupt underflow mode'
  else
     stop 'error setting underflow mode'
  end if

  fptest = 2e-36
  do i=1,50 ! 50 iterations max
     fptest = fptest * 0.5
     print '(e15.10)',fptest
     call ieee_get_flag(ieee_underflow,underflow)
     if (underflow) print *,'Underflow exception signaling'
     if (fptest == 0.0) exit
  end do

end program test

使用gfortran版本5.2.0,该程序输出:

代码语言:javascript
复制
This file was compiled by GCC version 5.2.0 using the options -mtune=generic -march=x86-64 -fno-unsafe-math-optimizations -frounding-math -fsignaling-nans
 Underflow control supported for the default real kind
 Able to set abrubpt underflow mode
.1000000036E-35
.5000000180E-36
.2500000090E-36
.1250000045E-36
.6250000225E-37
.3125000112E-37
.1562500056E-37
.0000000000E+00
 Underflow exception signaling

编译器选项标志-fno-unsafe-math-optimizations -frounding-math -fsignaling-nans由gfortran5.2文档建议,在任何时候使用IEEE模块以确保对标准的依附。

票数 9
EN

Stack Overflow用户

发布于 2019-03-12 20:48:40

“刷新为零”的一种懒散方法是使用gfortran的-funsafe-math-optimizations来:

允许可能违反IEEE或ISO标准的数学优化

或在其他词语

此模式支持允许任意重新组合和转换的优化,而不提供精确保证。它也不试图保留零的符号。

例如,small.f

代码语言:javascript
复制
      program test
        real r
        r=1e-40
        print *,'r on next line'
        print *,r
      end program

如果没有任何标志,则显示一个非零的非正态(小)数,没有错误:

代码语言:javascript
复制
$ gfortran -g small.f
$ ./a.out
 r on next line
   9.99994610E-41

捕获取消规范化的数字,当试图打印值时,该数字会崩溃:

代码语言:javascript
复制
$ gfortran -g -ffpe-trap=denorm small.f
$ ./a.out
 r on next line

Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.

Backtrace for this error:
#0  0x2aaaab05c26f in ???
#1  0x2aaaaac61aed in get_float_string
        at ../../../libgfortran/io/write_float.def:1064
#2  0x2aaaaac6423d in list_formatted_write_scalar
        at ../../../libgfortran/io/write.c:1889
#3  0x4008f1 in test
        at /path/to/small.f:5
#4  0x400941 in main
        at /path/to/small.f:6
Floating point exception

并添加了将其刷新为零的标志:

代码语言:javascript
复制
$ gfortran -g -ffpe-trap=denorm -funsafe-math-optimizations small.f
$ ./a.out
 r on next line
   0.00000000
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32851780

复制
相关文章

相似问题

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