| United States-English |
|
|
|
![]() |
HP-UX Floating-Point Guide: HP 9000 Computers > Chapter 4 HP-UX Math Libraries on HP 9000
SystemsMath Library Basics |
|
Math libraries in most computer systems, including HP-UX, are collections of frequently used mathematical functions. The functions take one or more arguments and return one or more results. When an application source file contains a use of a math function, the compiler automatically generates a call to the appropriate routine name in the appropriate math library. For example, suppose your Fortran program contains the following declaration and statement:
The statement raises A to the power B and assigns the result to Y. The Fortran compiler emits a call to FTN_DTOD, which is one of the functions in libcl.a and libcl.sl. libcl is the Fortran and Pascal library. Conceptually, the definition of a math library function is simple; in this example, FTN_DTOD merely raises a DOUBLE PRECISION value to the power of another DOUBLE PRECISION value. However, there are practical questions about math library functions that the programmer should consider:
The answers to questions 1 and 2 are implementation-dependent. The answers to questions 3, 4, and 5 are determined by a variety of programming environment specifications, such as XPG4.2. Appendix A “The C Math Library” partially answers question 5 by listing the functions in the HP-UX C math library. The Fortran equivalents are the intrinsic functions; see the HP Fortran 90 Programmer's Reference or the HP FORTRAN/9000 Programmer's Reference for a list of these functions. The following section, which describes what happens when a program calls a math library function, provides some answers to questions 1 through 4. Figure 4-1 “Anatomy of a Math Library Call” shows a generalized flowchart of a math library function call, applicable to all languages and standards. The figure and the discussion that follows assume that the function takes one argument, but they also apply to functions that take more than one argument. Steps A through E of this process are described below. The compiler-generated call to a math library function includes code that
The function determines whether the argument is valid. All functions check for NaN arguments and make additional checks specific to the function. For example, a logarithmic function checks for negative or zero arguments; an exponential function checks to see if the argument is so large that the result would overflow. If the argument is valid, control passes to Step C, execution of the function. If the argument is not valid, control passes to Step D. The execution of the function involves performing the appropriate transformation on the argument(s). For most math functions, the result has the same data type as the argument, which is usually double-precision. The execution of the function actually consists of one of many possible paths through the function code. The nature of the argument usually determines the path taken. For example, there may be special paths for particular argument ranges, or there may be an argument reduction phase. Math library implementors tune the most frequently executed paths for optimal efficiency. Consequently, arguments that are unusual (for example, very large or very small) can cause noticeable performance degradation. If an argument proves to be invalid, control passes to the error-handling function of the library. When this happens, performance slows considerably; usually it is 2 to 3 orders of magnitude slower than for a valid argument. This follows from the basic assumption in math library design that errors are rare events. If you do not supply an error-handling function in your program, a math library call that encounters an illegal argument does some or all of the following, depending on which programming language you are using and which standards are being enforced:
Your program may cause any of the above steps to be modified or stopped and may also provide an error-handling subroutine or function to be invoked. “Math Library Error Handling for C” describes how these steps are performed for the C programmer in the XPG4.2 and SVID environments; “Math Library Error Handling for Fortran” describes how they are performed for the Fortran programmer. Users of other languages should refer to the appropriate language manual for details. The XPG4.2 and SVID specifications specify similar math library error handling, so we describe them together. The XPG4.2 specification is a superset of the ANSI C standard. To differentiate between XPG and SVID, HP-UX in the past implemented two separate C math libraries, libm and libM. The SVID libraries were libm.a and libm.sl; the XPG libraries were libM.a and libM.sl. Because the SVID3 and XPG4.2 standards are essentially identical, HP-UX now supplies only one library, libm. The libM library is now obsolete. All versions of libM are provided only as soft links to the corresponding versions of libm (see “Locations of the Math Libraries at Release 10.30” for details). The flowchart in Figure 4-2 “C Math Library Error Handling for the sqrt Function” summarizes the error handling in the SVID and XPG4.2 math libraries. We use the sqrt function as an example. If a C library function such as sqrt encounters an invalid argument, it ordinarily returns a default result that indicates a failure—a result that the function could not ordinarily return. The default result is usually a NaN, zero, or HUGE_VAL, depending on the function and the argument value. In addition, some functions set the global value errno, defined in the header file errno.h. (Many HP-UX system calls also set this value.) When a library call fails, the value of errno may be set to an appropriate code, also defined by errno.h. The math library functions set errno to either EDOM or to ERANGE. EDOM indicates a domain error—that is, an error in the argument. ERANGE indicates a range error—usually an overflow in the result. To detect errors, an application should check both the returned value and errno. It may set errno to 0 (that is, no error) at the beginning of a section of code and then examine it after one or more library calls to see if it is nonzero. A nonzero value indicates that some sort of library error has occurred. For example, you could use the following C code fragment to print an error message when a call to pow fails:
If y is negative and w is not an integer value, this fragment would print out
If you look up 33 in the system include file /usr/include/sys/errno.h, you find that it indicates a domain error (EDOM). If a Fortran intrinsic function encounters an invalid argument, it returns a default result, just as a C function does. The default result depends on both the function and the nature of the argument. For example, a negative argument to the DLOG function causes it to return a NaN value. The most generally useful method of detecting errors is for the application to check for an anomalous result and then to take appropriate action. What happens after the error depends on the following factors:
We discuss the possible sequences of events in the following sections. The flowchart in Figure 4-3 “Fortran 77 Math Library Error Handling” summarizes HP FORTRAN/9000 math library error handling. The flowchart in Figure 4-4 “Fortran 90 Math Library Error Handling” summarizes HP Fortran 90 math library error handling. You can enable an exception trap for any of the five floating-point exception conditions described in “Exception Conditions”. The exception condition that indicates an invalid argument to a math library function is the invalid operation condition. You can enable a trap for this condition in any of several ways:
See Chapter 5 “Manipulating the Floating-Point Status Register” and Chapter 6 “Floating-Point Trap Handling” for information about all of these methods. If you do not enable a trap for invalid operations, all that happens in the case of an invalid argument is that the invalid operation exception flag in the status register is set and the default result is returned. You can retrieve the value of the exception flags by calling the fetestexcept routine, described in “Exception Bits”.
If you use +T to enable a trap for invalid operations, what happens next depends on whether your program contains an ON EXTERNAL ERROR statement. If it does not, the function merely returns the default result. If your program contains an ON statement, you must compile with the +T option in order to enable trap handling. If your program contains an ON statement and you do not specify +T, you get a compile-time warning. If your program does contain an ON statement, what happens depends on the action you specify in the statement. You can specify any of the following:
The following program illustrates Fortran 77 math library error handling. It calls DLOG with a negative argument, which is invalid. See “Run-Time Mode Control: The fenv(5) Suite” for information about the fetestexcept and fegettrapenable routines. Example 4-1 Sample Program: liberr77.f
If you compile this program with the ON statements commented out and without the +T option, no traps are enabled. Therefore, the math library error sets the appropriate exception flag. The output of the program is as follows:
The exception flag value indicates that both an invalid operation and an inexact result condition were generated. (Table 5-1 “IEEE Exception Bits” shows the bit values for each of these conditions.). If you compile with +T, the exception flags that correspond to the traps set by +T are not set after an error, and it is not useful to check them. If you remove the comment from the ON EXTERNAL ERROR ABORT statement and compile with +T, the invalid operation trap is enabled. When you run the program, it exits:
Finally, if you remove the comment from the ON EXTERNAL ERROR CALL MYSUB statement and compile with +T, the program calls the error-handling subroutine MYSUB before exiting:
HP does not support the use of the ON statement to handle math library errors in Fortran 90. The following is a Fortran 90 version of the program. Example 4-2 Sample Program: liberr90.f
If you compile the program as we show it, it runs as follows. Because no traps are enabled, the function returns a NaN and sets the appropriate exception flag.
If you compile the program with the +fp_exception option, the invalid operation trap is enabled, and the program aborts with an error message:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||