"Invalid" exception trapping

"Invalid" exception trapping

We have large generated programs that are compiled using CVF 6.6 and run on various Windows PCs. The compilation options we use (amongst others) are /FPE:0 /check_underflow and /optimize:0.

The programs occasionally generate floating point exceptions, which we trap in a C try-except block. The exception is then dealt with a Fortran error handling routine.

It is important that the exception is trapped immediately, because then we have the context for the error and can report it properly.

This works very well for most exceptions. Underflow, Overflow and Zero Divide are trapped, and Denormal is delibrately ignored. Unfortunately we cannot cause the Invalid exception, the number concerned just becomes NaN, which we don't want.

I have tried various ways of clearing the Invalid control bit (which means generate exceptions) in the floating point control word, but with no avail.

If anybody else has come across this problem and has a solution, please reply!

Eddie Breeveld

5 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项

I'm sorry, my post is slightly misleading.

The calculation that causes the problem is in the form:
a=0.0*b*c/d
where a, b, c and d are double precision; b and c are non-zero, and c is zero.

When we compile with FPE:3 we get NaN for the result.
When we compile with FPE:0 we get 0.0 for the result, when instead we want to trap an Invalid exception.

Eddie

subroutine SetExceptionHandlingFlags()  
	use dflib  
	implicit none  
c  
c	2001 07 16	bb		Original Code  
c  
c	This routine sets the floating point processor control
c       word.  This enables hardware exceptions to be trapped  
c	(caught) by the operating system.  Hardware exceptions
c       include floating point divide by zeros, underflow,
c       overflow, etc.  The control word is composed of bits
c       that control if a particular type of floating point
c       exception is enabled (unmasked) or not.  To enable the
c       exception, the corresponding bit is set to zero.  
c	See the Visual Fortran documentation for more details.
c       Search under:  
c	'Exceptions->Floating Point'.  
c  
  
	integer*2 controlword  
c  

c  
  
	CALL GETCONTROLFPQQ (controlword)   
	controlword = controlword .and. (.not. FPCW$ZERODIVIDE) .and.   
     *			  (.not. FPCW$OVERFLOW) ! .and. (.not. FPCW$UNDERFLOW)  
	call setcontrolfpqq(controlword)  
  
	  
	end

Thanks for the suggestion. Unfortunately we are having problems with the FPCW$INVALID bit in the control mask - all the others are working OK!

Eddie

Try this
...
use dflib
implicit none

!Local
integer(2) :: control = 0 !Current cw
integer(4) :: FPE_STS = 0, FPE_MASK = 0 !fpe masks

!An exception is dis/enabled if its flag is set/cleared to 1/0

Call GETCONTROLFPQQ(control)
!Clear all cw flags
control = control .AND. #0000
!Set cw to VC++ x86 default: all fpe traps disabled
control = FPCW$NEAR + FPCW$53 + FPCW$INVALID + FPCW$ZERODIVIDE + FPCW$OVERFLOW + FPCW$UNDERFLOW + FPCW$DENORMAL + FPCW$INEXACT
Call SETCONTROLFPQQ(control)
!Mask fp
!overflow,
!division by zero,
!and invalid
FPE_MASK = FPE_M_TRAP_OVF + FPE_M_TRAP_DIV0 + FPE_M_TRAP_INV
!To mask fp underflow, include FPE_M_TRAP_UND or via
!the Runtime Error Checking 'Underflow' option
FPE_STS = FOR_SET_FPE(FPE_MASK)
!The foregoing is equivalent to the CVF defaults, ie,
!53-bit precision,
!round to nearest,
!disable the
!denormal, underflow. and inexact precision exceptions
!and enable the overflow, division by zero, and invalid traps.
...
HTH

发表评论

登录添加评论。还不是成员?立即加入