2015-09-29 2 views
3

Есть ли способ принудительно сбросить поток с нуля в gfortran?Flush-to-zero in gfortran

Я не могу поверить, что это первый раз, когда кто-то спросил об этом, но я ничего не мог найти на нем. Mea culpa, если это дубликат.

+0

Пожалуйста, используйте общий [тег: fortran], не многие люди следуют отдельным версиям, и ваш вопрос не является специфичным для Fortran. –

+2

некоторые обсуждения темы здесь: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36821 – agentp

ответ

6

Вы можете выполнить это с помощью последних версий 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 используются для обеспечения соблюдения стандарта.

+0

Очень полный ответ. Спасибо! –

Смежные вопросы