Numerical Computation Guide |
Standards Compliance
The compilers, header files, and libraries in the Sun WorkShop Compilers products for the Solaris environment support multiple standards: System V Interface Definition (SVID), Edition 3, X/Open and ANSI C. Accordingly, the mathematical library
libm
and related files have been modified so that C programs comply with the standards. Users' programs are usually not affected, because the differences primarily involve exception handling.SVID History
To understand the differences between exception handling according to SVID and the point of view represented by the IEEE Standard, it is necessary to review the circumstances under which both developed. Many of the ideas in SVID trace their origins to the early days of UNIX, when it was first implemented on mainframe computers. These early environments have in common that rational floating-point operations
+
, -,*
and/
are atomic machine instructions, whilesqrt
, conversion to integral value in floating-point format, and elementary transcendental functions are subroutines composed of many atomic machine instructions.Because these environments treat floating-point exceptions in varied ways, uniformity could only be imposed by checking arguments and results in software before and after each atomic floating-point instruction. Because this has too great an impact on performance, SVID does not specify the effect of floating-point exceptions such as division by zero or overflow.
Operations implemented by subroutines are slow compared to single atomic floating-point instructions; extra error checking of arguments and results has little performance impact; so such checking is required by the SVID. When exceptions are detected, default results are specified,
errno
is set toEDOM
for improper operands, orERANGE
for results that overflow or underflow, and the functionmatherr()
is called with a record containing details of the exception. This costs little on the machines for which UNIX was originally developed, but the value is correspondingly small because the far more common exceptions in the basic operations+
, -,*
and/
are completely unspecified.IEEE 754 History
The IEEE Standard explicitly states that compatibility with previous implementations was not a goal. Instead, an exception handling scheme was developed with efficiency and users' requirements in mind. This scheme is uniform across the simple rational operations (
+
, -,*
and/
), and more complicated operations such as remainder, square root, and conversion between formats. Although the Standard does not specify transcendental functions, the framers of the Standard anticipated that the same exception handling scheme would be applied to elementary transcendental functions in conforming systems.Elements of IEEE exception handling include suitable default results and interruption of computation only when requested in advance.
SVID Future Directions
The current SVID, ("Edition 3" or "SVR4"), identifies certain directions for future development. One of these is compatibility with the IEEE Standard. In particular a future version of the SVID replaces references to
HUGE
, intended to be a large finite number, withHUGE_VAL
, which is infinity on IEEE systems.HUGE_VAL
, for instance, is returned as the result of floating-point overflows. The values returned bylibm
functions for input arguments that raise exceptions are those in the IEEE column in TABLE E-1. In addition,errno
no longer needs to be set.SVID Implementation
The following
libm
functions provide operand or result checking corresponding to SVID. Thesqrt
function is the only function that does not conform to SVID when called from a C program that uses thelibm
in-line expansion templates through-xlibmil
, because this causes the hardware instruction for square root,fsqrt[sd]
, to be used in place of a function call.
General Notes on Exceptional Cases and
libm
FunctionsTABLE E-1 lists all the
libm
functions affected by the standards. The valueX_TLOSS
is defined in<values.h>
. SVID requires<math.h>
to defineHUGE
asMAXFLOAT
, which is approximately 3.4e+38.HUGE_VAL
is defined as infinity inlibc. errno
is a global variable accessible to C and C++ programs.
<errno.h>
defines 120 or so possible values forerrno
; the two used by the math library areEDOM
for domain errors andERANGE
for range errors. Seeintro
(3) andperror
(3).
- The ANSI C compiler switches -
Xt
, -Xa
, -Xc
, -Xs
, among other things, control the level of standards compliance that is enforced by the compiler. Refer tocc
(1) for a description of these switches.- As far as
libm
is concerned, -Xt
and -Xa
cause SVID and X/Open behavior, respectively. -Xc
corresponds to strict ANSI C behavior.
- An additional switch -
<x>libmieee
, when specified, returns values in the spirit of IEEE 754. The default behavior forlibm
andlibsunmath
is to be SVID-compliant on Solaris 2.6, Solaris 7, and Solaris 8.
- For strict ANSI C (-
Xc
),errno
is set always,matherr
() is not called, and the X/Open value is returned.- For SVID (-
Xt
or -Xs
), the functionmatherr
() is called with information about the exception. This includes the value that is the default SVID return value.
- A user-supplied
matherr
() could alter the return value; seematherr
(3m). If there is no user-suppliedmatherr()
,libm
setserrno
, possibly prints a message to standard error, and returns the value listed in the SVID column of TABLE E-1 on page 255.
- For X/Open (-
Xa
), the behavior is the same as for the SVID, in thatmatherr
() is invoked anderrno
set accordingly. However, no error message is written to standard error, and the X/Open return values are the same as IEEE return values in many cases.- For the purposes of
libm
exception handling, -Xs
behaves the same as -Xt
. That is, programs compiled with -Xs
use the SVID compliant versions of thelibm
functions listed in TABLE E-1 on page 255.- For efficiency, programs compiled with inline hardware floating-point do not do the extra checking required to set
EDOM
or callmatherr()
ifsqrt
encounters a negative argument.NaN
is returned for the function value in situations whereEDOM
might otherwise be set.
- Thus, C programs that replace
sqrt()
function calls withfsqrt[sd]
instructions conform to the IEEE Floating-Point Standard, but may no longer conform to the error handling requirements of the System V Interface Definition.Notes on
libm
SVID specifies two floating-point exceptions,
PLOSS
(partial loss of significance) andTLOSS
(total loss of significance). Unlikesqrt(
-1)
, these have no inherent mathematical meaning, and unlikeexp(+
-10000)
, these do not reflect inherent limitations of a floating-point storage format.
PLOSS
andTLOSS
reflect instead limitations of particular algorithms forfmod
and for trigonometric functions that suffer abrupt declines in accuracy at definite boundaries.Like most IEEE implementations, the
libm
algorithms do not suffer such abrupt declines, and so do not signalPLOSS
. To satisfy the dictates of SVID compliance, the Bessel functions do signalTLOSS
for large input arguments, although accurate results can be safely calculated.The implementations of
sin
,cos
, andtan
treat the essential singularity at infinity like other essential singularities by returning aNaN
and settingEDOM
for infinite arguments.Likewise SVID specifies that
fmod(x,y)
is be zero ifx/y
overflows, but thelibm
implementation offmod
, derived from the IEEE remainder function, does not computex/y
explicitly and hence always delivers an exact result.LIA-1 Conformance
In this section, LIA-1 refers to ISO/IEC 10967-1:1994 Information Technology - Language Independent Arithmetic - Part 1: Integer and floating-point arithmetic.
The C and Fortran-77 compilers (
cc
andf77
) contained in the Sun WorkShop Compilers 6.0 release conform to LIA-1 in the following senses (paragraph letters correspond to those in LIA-1 section 8):a. TYPES (LIA 5.1): The LIA-1 conformant types are C int and Fortran
INTEGER
. Other types may conform as well, but they are not specified here. Further specifications for specific languages await language bindings to LIA-1 from the cognizant language standards organizations.#include <values.h> /* defines MAXINT */ #define TRUE 1 #define FALSE 0 #define BOUNDED TRUE #define MODULO TRUE #define MAXINT 2147483647 #define MININT -2147483648 logical bounded, modulo integer maxint, minint parameter (bounded = .TRUE.) parameter (modulo = .TRUE.) parameter (maxint = 2147483647) parameter (minint = -2147483648)C / and %, and Fortran / and mod(), provide DIVtI(x,y) and REMtI(x,y). Also, modaI(x,y) is available with this code:
int modaI(int x, int y) { int t = x % y; if (y < 0 && t > 0) t -= y; else if (y > 0 && t < 0) t += y; return t; }integer function modaI(x, y) integer x, y, t t = mod(x, y) if (y .lt. 0 .and. t .gt. 0) t = t - y if (y .gt. 0 .and. t .lt. 0) t = t + y modaI = t return endi. NOTATION (LIA 5.1.3): The following table shows the notation by which the LIA integer operations may be realized.
The following code shows the Fortran notation for
signI(x)
.integer function signi(x) integer x, t if (x .gt. 0) t=1 if (x .lt. 0) t=-1 if (x .eq. 0) t=0 return endj. EXPRESSION EVALUATION: By default, when no optimization is specified, expressions are evaluated in
int
(C) orINTEGER
(Fortran) precision. Parentheses are respected. The order of evaluation of associative unparenthesized expressions such as a + b + c or a * b * c is not specified.k. METHOD OF OBTAINING PARAMETERS: Include the definitions above in the source code.
n. NOTIFICATION: Integer exceptions are x/0 and x%0 or mod(x,0). By default, these exceptions generate
SIGFPE
. When no signal handler is specified forSIGFPE
, the process terminates and dumps memory.o. SELECTION MECHANISM:
signal
(3) orsignal
(3F) may be used to enable user exception handling forSIGFPE
.
Sun Microsystems, Inc. Copyright information. All rights reserved. Feedback |
Library | Contents | Previous | Next | Index |