Есть ли способ принудительно сбросить поток с нуля в gfortran?Flush-to-zero in gfortran
Я не могу поверить, что это первый раз, когда кто-то спросил об этом, но я ничего не мог найти на нем. Mea culpa, если это дубликат.
Есть ли способ принудительно сбросить поток с нуля в gfortran?Flush-to-zero in gfortran
Я не могу поверить, что это первый раз, когда кто-то спросил об этом, но я ничего не мог найти на нем. Mea culpa, если это дубликат.
Вы можете выполнить это с помощью последних версий gfortran, которые поддерживают модули IEEE Fortran 2003. Стандарт определяет два режима нижнего потока - постепенный и резкий. Abrupt - это тот, который вы хотите, который устанавливает нижний поток в 0 и сигнализирует исключение с плавающей запятой underflow. Вы можете протестировать поддержку управления режимом underflow с помощью функции ieee_support_underflow_control(X)
, которая проверяет управление потоком для вида реального X и возвращает логическое значение true, если оно поддерживается. Если поддерживается, вы можете затем call ieee_set_underflow_mode(.false.)
установить режим резкого понижения.
Ниже тестовая программа вы можете использовать для тестирования сгущенного поддержки управления по умолчанию реального вида на:
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, эта программа выводит:
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
предлагаются документацией gfortran 5.2 для использования в любое время, когда модули IEEE используются для обеспечения соблюдения стандарта.
Очень полный ответ. Спасибо! –
Пожалуйста, используйте общий [тег: fortran], не многие люди следуют отдельным версиям, и ваш вопрос не является специфичным для Fortran. –
некоторые обсуждения темы здесь: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36821 – agentp