Chapter Contents

Previous

Next
SAS/C Library Changes in Release 7.50

Updates to Mathematical Functions

In Chapter 2, "Function Categories," replace the section titled, "Mathematical Functions,"with the following text.

The SAS/C library of mathematical functions includes the full complement of math functions from the ANSI/ISO C standard, plus additional functions commonly implemented on UNIX systems. It also includes the math functions defined by the ISO C99 standard. All functions are provided for both hexadecimal and binary floating point inputs. Some functions are not applicable to hexadecimal floating point, and may return meaningless results when called in that environment.

When a math function is called, the version called is determined by the manner in which the calling function was compiled. If the bfp option was used, the IEEE function is called; otherwise, the traditional mainframe function is called. If necessary, the argument is converted to the proper format first, assuming an appropriate header file was included.


Math Header Files

The following header files are useful to users of the mathematical library:

fenv.h
defines symbols, types, and functions supporting inspection and modification of the floating-point environment. These facilities are generally useful only with binary floating point. This is a standard C99 header file.

fenvtrap.h
defines functions supporting control of floating-point trapping. These facilities are generally useful only with binary floating point.

float.h
defines preprocessor symbols specifying the characteristics of System/390 floating point. This is an ANSI/ISO standard header file.

lcfloat.h
defines non-standard preprocessor symbols defining constants, such as infinities and NaNs, of various types.

lcmath.h
defines non-standard mathematical preprocessor symbols and library functions.

math.h
defines preprocessor symbols and functions supporting the standard mathematical library. The is a standard ANSI/ISO header file. It includes symbols and function prototypes from C99. These can be removed by defining the preprocessor symbol _SASC_HIDE_C99MATHLIB before including math.h.

tgmath.h
defines macro versions of most of the mathematical functions. The macros are type-generic, that is, the same function name can be used for float, double, or long double arguments. See Float and Long Double Functions for further information.


Preprocessor Symbols

The following lists contain the preprocessor symbols defined by the math-related header files.

The fenv.h header file contains the following preprocessor symbols:

Exception bits
FE_INVALID
FE_DIVBYZERO
FE_OVERFLOW
FE_UNDERFLOW
FE_INEXACT
FE_ALL_EXCEPT

Rounding modes
FE_TONEAREST
FE_TOWARDZERO
FE_UPWARD
FE_DOWNWARD

Default floating point environment
FE_DFL_ENV

Note:   If the bfp option is not used, FE_DFL_ENV is the only symbol that is defined.  [cautionend]

The float.h header file contains the following preprocessor symbols:
FLT_EVAL_METHOD
FLT_RADIX
FLT_ROUNDS
FLT_MANT_DIG
FLT_DIG
FLT_MIN_EXP
FLT_MIN_10_EXP
FLT_MAX_EXP
FLT_MAX_10_EXP
FLT_MAX
FLT_EPSILON
FLT_MIN
DBL_MANT_DIG
DBL_DIG
DBL_MIN_EXP
DBL_MIN_10_EXP
DBL_MAX_EXP
DBL_MAX_10_EXP
DBL_MAX
DBL_EPSILON
DBL_MIN
LDBL_MANT_DIG
LDBL_DIG
LDBL_MIN_EXP
LDBL_MIN_10_EXP
LDBL_MAX_EXP
LDBL_MAX_10_EXP
LDBL_MAX
LDBL_EPSILON
LDBL_MIN

Note:   See the C standards documents for details on the meanings of these symbols.  [cautionend]

The lcfloat.h header file contains the following preprocessor symbols:

FLT_INFINITY
specifies a float infinity.

FLT_QNAN
specifies a float quiet not-a-number (NaN).

FLT_SNAN
specifies a float signaling NaN.

DBL_INFINITY
specifies a double infinity.

DBL_QNAN
specifies a double quiet NaN.

DBL_SNAN
specifies a double signaling NaN.

LDBL_INFINITY
specifies a long double infinity.

LDBL_QNAN
specifies a long double quiet NaN.

LDBL_SNAN
specifies a long double signaling NaN.

Note:   Since hexadecimal floating-point does not support NaNs or infinities, these symbols have little utility in a hexadecimal floating-point environment.  [cautionend]

The lcmath.h header file contains the following constant representations:

Constant Values Declared in lcmath.h
Constant Representation
DOMAIN matherr exception code - domain error
SING exception - singularity
OVERFLOW exception - overflow
UNDERFLOW exception - underflow
TLOSS exception - total loss of significance
PLOSS exception - partial loss of significance
M_PI The constant [pi]
M_PI_2 [pi]/2
M_PI_4 [pi]/4
M_1_PI 1/[pi]
M_2_PI 2/[pi]
M_E The constant e
HUGE The largest finite double
TINY The smallest non-zero positive double
LOGHUGE log(HUGE)
LOGTINY log(TINY)

The math.h header file contains the following preprocessor symbols:

HUGE_VALF
the largest float, possibly infinite

HUGE_VAL
the largest double, possibly infinite

HUGE_VALL
the largest long double, possibly infinite

INFINITY
positive infinity (compile-time error if not BFP)

NAN
a float quiet NaN (not defined for HFP)

FP_ZERO
number classification macro

FP_NORMAL
number classification macro

FP_SUBNORMAL
number classification macro

FP_INFINITE
number classification macro

FP_NAN
number classification macro

FP_FAST_FMA
fast multiply and add double support - BFP only

FP_FAST_FMAF
fast multiply and add float support - BFP only

FP_FAST_FMAL
fast multiply and add long double support - BFP only

FP_ILOGB0
result of ilogb(0)

FP_ILOGBNAN
result of ilogb(NaN)

MATH_ERRNO
math function error handling constant

MATH_ERREXCEPT
math function error handling constant

math_errhandling
math function error handling constant


Type Definitions

The math header files include definitions of the following types:

<fenv.h>
    fenv_t         /* represents a floating-point environment */
    fexcept_t      /* represents floating-point exception information */

<lcmath.h>
    struct exception  /* A structure containing error information */

<math.h>
    float_t        /* effective type of float (see C99) */
    double_t       /* effective type of double (see C99) */


Function Categories

Because of the size of the math library, it is useful to divide it into several sublibraries of functions with similar characteristics. The categories and the functions they contain are listed below. Each function name may be followed by a notation indicating whether the function is defined for arguments of type float or long double. The notations are as follows:
(f) A variant function accepts float arguments. The name is formed by adding an f to the end of the base function name.
(g) A type-generic version of the function is defined in tgmath.h.
(l) A variant function accepts long double arguments. The name is formed by adding an l to the end of the base function name.
(m) The function is a macro, and accepts arguments of any floating-point type.


Floating-point Environment Functions

These functions enable you to access and manipulate the floating- point environment, such as exception flags and rounding modes. In general, these functions are useful only when IEEE floating-point is used. If you do not use the bfp option in your compilation, these functions have no effect and do not return meaningful results.

Any compilation which uses these functions must include a pragma of the following form

    #pragma STDC FENV_ACCESS ON

in an enclosing scope. If this pragma is not used, the effects of accessing or modifying the floating-point environment via these functions is undefined. The FENV_ACCESS pragma may reduce optimization, and therefore should be used only when necessary.

These functions are defined in the header file fenv.h except for fegettrapenable and fesettrapenable, which are defined in fenvtrap.h. None of these functions should be used without including the appropriate header file.

The floating-point environment functions are:
feclearexcept clear floating-point exception flags
fegetenv extract the floating-point environment
fegetexceptflag extract floating-point exception flags
fegetround get the floating-point rounding mode
fegettrapenable get the floating-point trap status
feholdexcept clear and hold floating-point exceptions
feraiseexcept raise a floating-point exception
fesetenv modify the floating-point environemnt
fesetexceptflag set floating-point exception flags
fesetround set the floating-point rounding mode
fesettrapenable set the floating-point trap status
fetestexcept test for floating-point exceptions
feupdateenv update the floating-point environment


Type Classification Functions

These functions are defined in the header file math.h. With the exception of copysign, all of these functions are defined as macros that accept any floating-point argument type. These functions have limited utility with traditional mainframe floating point.

The type classification functions are:
copysign (f,g,l) propagate sign from one value to another
fpclassify (m) classify a floating-point value
isfinite (m) test for finite floating-point value
isinf (m) test for infinite floating-point value
isnan (m) test for NaN
isnormal (m) test for normal (non-zero, normalized) floating-point value
signbit (m) return the sign of a floating-point number


Comparison Functions

These functions are defined in the header file math.h. They are defined as generic macros, and they take any floating-point type for arguments. They differ from the standard C comparison operators because they do not raise the invalid floating-point exception if an argument is a NaN. Thus, for traditional mainframe floating-point, which has no NaNs, they are completely equivalent to the standard operators. Because these functions are implemented as macros, it is necessary to include math.h to use them.

The comparison functions are:

isgreater (m)
compare for greater than

isgreaterequal (m)
compare for greater than or equal

isless (m)
compare for less than

islessequal (m)
compare for less than or equal

islessgreater (m)
compare for less or greater than

isunordered (m)
test for unordered


Low-level Functions

These functions are defined in math.h or lcmath.h. Unlike the transcendental functions, these functions perform low-level floating-point operations that are often closely connected with their representation in memory. All of these functions are defined in the C99 standard except for _ldexp, whose prototype is in the non-standard header file lcmath.h.

The low-level functions are:
_ldexp fast ldexp implementation
ceil (f,g,l) floating-point ceiling
fabs (f,g,l) floating-point absolute value
fdim (f,g,l) floating-point positive difference
floor (f,g,l) floating-point floor
fma (f,g,l) floating-point multiply and add
fmax (f,g,l) floating-point maximum
fmin (f,g,l) floating-point minimum
fmod (f,g,l) floating point modulus
frexp (f,g,l) split into fraction and exponent
ilogb (f,g,l) integer floating-point exponent
ldexp (f,g,l) scale by power of 2
llrint (f,g,l) convert floating-point to long long
llround (f,g,l) round floating-point to long long
logb (f,g,l) floating-point exponent
lrint (f,g,l) convert floating-point to long
lround (f,g,l) round floating-point to long
modf (f,l) split into integer and fraction
nearbyint (f,g,l) return nearest integer
nextafter (f,g,l) return next floating-point value
nexttoward (f,g,l) return next floating-point value
remainder (f,g,l) floating-point remainder
remquo (f,g,l) floating-point remainder and partial quotient
rint (f,g,l) convert to floating-point integer
round (f,g,l) round to floating-point integer
scalbln (f,g,l) scale by power of radix (long exponent)
scalbn (f,g,l) scale by power of radix (int exponent)
trunc (f,g,l) truncate to floating-point integer


Transcendental Functions

These functions are the functions traditionally known as math functions. They have mathematical definitions with no direct relationship to their hardware representations.

Most of these functions are defined in the C99 standard. The functions, gamma, j0, j1, jn, y0, y1, and yn are non-standard functions frequently implemented in UNIX systems. The prototypes for these functions are in the non-standard header file lcmath.h.
acos (f,g,l) arc cosine
acosh (f,g,l) arc hyperbolic cosine
asin (f,g,l) arc sine
asinh (f,g,l) arc hyperbolic sine
atan (f,g,l) arc tangent
atan2 (f,g,l) arc tangent of quotient
atanh (f,g,l) arc hyperbolic tangent
cbrt (f,g,l) cube root
cos (f,g,l) cosine
cosh (f,g,l) hyperbolic cosine
erf (f,g,l) error function
erfc (f,g,l) complementary error function
exp (f,g,l) exponential
exp2 (f,g,l) binary exponential (2 ** x)
expm1 (f,g,l) exponential minus 1
gamma log gamma function
hypot (f,g,l) hypoteneuse
j0 Bessel function of the first kind, order 0
j1 Bessel function of the first kind, order 1
jn Bessel function of the first kind, order n
lgamma (f,g,l) log gamma function
log (f,g,l) logarithm base e
log10 (f,g,l) logarithm base 10
log1p (f,g,l) logarithm of argument plus 1
log2 (f,g,l) logarithm base 2
pow (f,g,l) power function
sin (f,g,l) sine
sinh (f,g,l) hyperbolic sine
sqrt (f,g,l) square root
tan (f,g,l) tangent
tanh (f,g,l) hyperbolic tangent
tgamma (f,g,l) gamma function
y0 Bessel function of the second kind, order 0
y1 Bessel function of the second kind, order 1
yn Bessel function of the second kind, order n


Math Function Error Handling

Most of the transcendental math functions are subject to errors. Errors may be broadly characterized as domain errors, where a function is called in a way that is not mathematically meaningful, for example, sqrt(-5.0), and range errors, where the function result cannot be represented, for example, exp(10000.0). The transcendental math library handles these errors in a uniform way that the following list provides details for.

The above rules apply specifically to the transcendental functions. The low-level functions are oriented towards performance rather than error detection, and may not abide by all these rules. In particular, a low-level function might trap, might fail without producing a diagnostic or setting errno, and might produce a diagnostic without calling _matherr or _matherb. For IEEE floating-point, these low-level functions will set the floating-point status bits correctly, even when they do not write a diagnostic or set errno.


Float and Long Double Functions

For most of the functions discussed above, the most commonly used form is one that accepts double arguments and returns double results. Depending on the function, the C99 standard defines two different ways that these functions may be generalized to accept float or long double arguments.

Some functions are defined as macros, which can accept any floating-point type. For example,

    float fl;
    double d;    
    long double ld;

    if (isnormal(fl) /* float argument */ &&
        isnormal(d)  /* double argument */ &&
        isnormal(ld)) /* long double argument */ ...

The macros produce undefined results if they are passed an argument that does not have floating-point type. A call such as isnormal(4) is not valid.

The remaining functions are defined as families of functions. They comprise a base function accepting double arguments and related functions accepting float arguments and long double arguments. For example,

    ld = asinf(fl) /* float argument */ +
         acos(d)   /* double argument */ +
         atan2l(ld, ld+1);  /* long double arguments */

Because these are functions defined by prototypes in math.h, they can be called with arguments which fail to match the expected type; such arguments will be converted, or diagnosed as incorrect if conversion is impossible. For example, the following expression

    sqrt(fl) /* argument converted to double */ *
    cbrtf(6) /* argument converted to float */

is valid and well-defined.

Because use of the traditional function names without any suffixes can add clarity and readability to code, C99 also added the tgmath.h header file. When this header file is included, most of the mathematical functions are redefined as type-generic macros, which select the proper function based on the type of their arguments. Thus, if tgmath.h is included, the expression acos(f) will invoke the float arc-cosine function, acosf, without converting the argument to double.

Note that, in many cases, the float and long double versions of a function can call the double version. If a call to a float or long double function version is incorrect, the generated diagnostic might reference the double function name, depending on where the error was detected.


New Math Functions

Add the following function descriptions to Chapter 6, "Function Descriptions" in SAS/C Library Reference, Volume 1.

The C99 portability term indicates that the function is defined by C99, not by C89.


Chapter Contents

Previous

Next

Top of Page

Copyright © 2004 by SAS Institute Inc., Cary, NC, USA. All rights reserved.