next up previous contents
Next: CONSTANTS
Up: THE NUM_ FUNCTIONS
Previous: Declaring and Defining the NUM_ Functions


NUM Error Handling

Because the NUM_ functions do not have any built-in error handling capability, the NUM facility provides a simple VAX condition handler which may be used to explicitly implement error handling, both for the NUM_ functions and straightforward Fortran arithmetic expressions.

Note that using this capability involves calls to VAX Run Time Library (RTL) routines and will therefore result in applications which are not portable. Such applications will continue to operate, however, if the RTL calls are simply removed, although error handling will not then occur.

The technique is best explained by an example:

      SUBROUTINE EXAMPL( N, DATA )                
                                                  
*   Declare constants and variables.              
      INCLUDE 'SAE_PAR'                           
      INCLUDE 'PRM_PAR'                           
      INTEGER N, I                                
      REAL DATA( N )                              
                                                  
*   Declare the condition handler.                
      INTEGER NUM_TRAP                            [1]
      EXTERNAL NUM_TRAP                           
                                                  
*   Include the NUM_CMN common block definition, which defines
*   the variable NUM_ERROR.                       
      INCLUDE 'NUM_CMN'                           [2]
                                                  
*   Establish the condition handler.              
      CALL LIB$ESTABLISH( NUM_TRAP )              [3]
                                                  
*   Initialise.                                   
      NUM_ERROR = SAI__OK                         [4]
                                                  
*   Perform the calculations.                     
      DO 1 I = 1, N                               
         DATA( I ) = 1.0 / ( DATA( I ) ** 2 )     [5]
                                                  
*   Check if an error occurred.                   
         IF( NUM_ERROR .NE. SAI__OK ) THEN        [6]
                                                  
*   If so, reset the NUM_ERROR flag and define the result.
            NUM_ERROR = SAI__OK                   [7]
            DATA( I ) = VAL__BADR                 
         ENDIF                                    
    1 CONTINUE                                    
                                                  
*   Remove the condition handler and exit the routine.
      CALL LIB$REVERT                             [8]
      END

Programming notes:

  1. The integer function NUM_TRAP is provided as a standard condition handler which traps numerical errors. This routine must be declared in an EXTERNAL statement.

  2. The common block NUM_CMN is defined using an INCLUDE statement. It contains a single integer variable called NUM_ERROR which communicates with the condition handler.

  3. The VAX RTL routine LIB$ESTABLISH is called to establish the condition handler. From this point on, numerical errors will not cause the application to crash, but will be intercepted by the NUM_TRAP routine. This behaviour is local to the routine from which LIB$ESTABLISH is called. The behaviour of VAL_ and VEC_ routines and the handling of non-numerical errors is not affected.

  4. The common block variable NUM_ERROR is initialised to SAI__OK. This is important because numerical errors will not be detected otherwise.

  5. Calculations are performed which may potentially fail. These may include calls to NUM_ functions and need not be confined to a single expression or statement. In the above example floating point overflow or division by zero could occur, according to the contents of the DATA array.

  6. After a calculation, the status variable NUM_ERROR is tested. If it is not SAI__OK, then a numerical error has occurred. The value of NUM_ERROR may be used as a status code for reporting the error if required.

  7. If an error has occurred, suitable action is taken. This must include resetting the numerical error status NUM_ERROR to SAI__OK and defining the result of any calculations which failed. This will usually be done using a flag for later identification (normally one of the Starlink bad values).

  8. Finally, the condition handler is removed by calling the RTL routine LIB$REVERT. This is strictly only necessary if further calculations which do not require error handling are to be performed in the same routine.

It is important to note that when a calculation fails, more than one numerical error may occur. This is because the (erroneous) result of the first operation to fail can be re-used in subsequent parts of an arithmetic expression and may precipitate further errors. To ensure that NUM_ERROR indicates the true (first) cause of an error in such cases, this variable behaves as a latch; once set, it will not again change in response to an error until it has first been reset to SAI__OK.

Note also, that the result of a calculation which fails (or may have failed) must not be used under any circumstances. It may either contain an erroneous result or an invalid floating point number (a reserved operand) which will cause any application which processes it to crash. Such results must immediately be replaced with a well-defined value.


next up previous contents
Next: CONSTANTS
Up: THE NUM_ FUNCTIONS
Previous: Declaring and Defining the NUM_ Functions

PRIMDAT --- Processing of Primitive Numerical Data
Starlink User Note 39
R F Warren-Smith
28 February 1995
E-mail:ussc@star.rl.ac.uk

Copyright © 2009 Science and Technology Facilities Council