Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

floating-point exception

beam2000
Beginner
1,096 Views

Created a new project on the basis of an example on usage of procedure CLEARSTATUSFPQQ from Intel Fortran Compiler User and Reference Guides:

! Program to demonstrate CLEARSTATUSFPQQ.

! This program uses polling to detect that a

! floating-point exception has occurred.

! So, build this console application with the default

! floating-point exception behavior, fpe3.

! You need to specify compiler option /debug or /Od (Windows)

! or -O0 (Linux) to get the correct results

! PROGRAM CLEARFP

USE IFPORT

REAL*4 A,B,C

INTEGER*2 STS

A = 2.0E0

B = 0.0E0

! Poll and display initial floating point status

CALL GETSTATUSFPQQ(STS)

WRITE(*,'(1X,A,Z4.4)') 'Initial fp status = ',STS

! Cause a divide-by-zero exception

! Poll and display the new floating point status

C = A/B

CALL GETSTATUSFPQQ(STS)

WRITE(*,'(1X,A,Z4.4)') 'After div-by-zero fp status = ',STS

! If a divide by zero error occurred, clear the floating point

! status register so future exceptions can be detected.

IF ((STS .AND. FPSW$ZERODIVIDE) > 0) THEN

CALL CLEARSTATUSFPQQ()

CALL GETSTATUSFPQQ(STS)

WRITE(*,'(1X,A,Z4.4)') 'After CLEARSTATUSFPQQ fp status = ',STS

ENDIF

END

Installed compiler directive: /debug and /fpe:3

But as a result received on the screen following output:

Initial fp status = 0000

After div-by-zero fp status = 000

That is the program does not find out divide by zero?

In the Compaq Visual Fortran 6 program finds divide by zero!

0 Kudos
8 Replies
psantos
Beginner
1,096 Views
Hello beam2000,

I have tried your program and I have the same behaviour, but only when compiled under IA32. If I compile in x64, the "fp status" prints 4 (divided by zero). There is something wrong here, but I don't know what it could be... I'm using Composer XE update 2. What compiler are you using?

Pedro
0 Kudos
beam2000
Beginner
1,096 Views
Hello Pedro!

I have Intel Visual Fortran 11.1.060 [IA-32].

Sergey
0 Kudos
Steven_L_Intel1
Employee
1,096 Views
There are a couple of different things that may cause this difference. You might want to try adding the /arch:ia32 option (in Visual Studio that is project property Fortran > Code Generation > Enable Enhanced Instruction Set > No enhanced instruction sets. The SSE instructions used by Intel Fortran behave differently regarding the FP flags compared to the "X87" instructions in earlier versions.

A second possibility is a bug in the way the run-time library handles FP exceptions - use Intel Visual Fortran Composer XE 2011 to resolve that.

However, I'd suggest instead that you use the Fortran 2003 "IEEE Floating point" intrinsic modules to accomplish what you want. Here's an example:

[fortran]    program zerodivide

use, intrinsic :: IEEE_EXCEPTIONS
use, intrinsic :: IEEE_ARITHMETIC

implicit none


real :: a, b, c
logical :: zerodivide_flag

! Disable halting on a zerodivide

call IEEE_SET_HALTING_MODE (IEEE_DIVIDE_BY_ZERO, .FALSE.)

a = 2.0

! In a loop, read B from the console and divide it into A
do
read (*,*,END=99) b
! Clear the exception flags
call IEEE_SET_FLAG (IEEE_USUAL, .FALSE.)
c = a / b
! Did we get an exception?
call IEEE_GET_FLAG (IEEE_DIVIDE_BY_ZERO, zerodivide_flag)
if (zerodivide_flag) then
write (*,*) "Divide by zero!"
else
write (*,*) "Result is ", c
end if
end do

99 continue

end program zerodivide
[/fortran]
0 Kudos
beam2000
Beginner
1,096 Views

Thank you very much, Steve!!!

Sergey

0 Kudos
beam2000
Beginner
1,096 Views
Hi Steve!

If to compile the program presented by you in configuration Win32 Release with Optimization directive: Speed the acceptable result turns out. If thus to change 29 line on

write (*, *) "Result is ok"

the result will be unacceptable. Why?

Sergey

0 Kudos
Steven_L_Intel1
Employee
1,096 Views
Sergey, if I understand correctly, you're saying that if you change the WRITE to one that does not use the result of the division then you don't get an error. This is because the compiler sees that the division can be removed and therefore no zerodivide occurs.
0 Kudos
beam2000
Beginner
1,096 Views
Steve, but why in configuration Win32 Releasewith Optimization directive: Disable zerodivide occurs?
0 Kudos
Steven_L_Intel1
Employee
1,096 Views
Because you disabled the optimizer so it didn't remove the unused calculation.
0 Kudos
Reply