For historical reasons,
the math library is only defined for the floating type double
.
All the names formed by appending f
or l
to a name in <math.h>
are reserved to allow for the definition of
float
and long double
libraries.
The functions ecvt
, fcvt
, and gcvt
have been dropped since their capability is available through
sprintf
.
Traditionally, HUGE_VAL
has been defined as a
manifest constant
that approximates the largest representable double
value.
As an approximation to infinity it is problematic.
As a function return value indicating overflow,
it can cause trouble if first assigned to a float
before testing,
since a float
may not necessarily hold all values representable in a double
.
After considering several alternatives,
the Committee decided to generalize HUGE_VAL
to a positive double expression,
so that it could be expressed as
an external identifier naming a location initialized precisely with
the proper bit pattern.
It can even be a special encoding for machine infinity,
on implementations that support such codes.
It need not be representable as a float
, however.
Similarly, domain errors in the past were typically indicated by a zero return, which is not necessarily distinguishable from a valid result. The Committee agreed to make the return value for domain errors implementation-defined, so that special machine codes can be used to advantage. This makes possible an implementation of the math library in accordance with the IEEE P854 proposal on floating point representation and arithmetic.
Whether underflow should be considered a range error, and cause
errno
to be set, is specified as
implementation-defined
since detection of underflow is inefficient on some systems.
The Standard has been crafted to neither require nor preclude any popular implementation of floating point. This principle affects the definition of domain error: an implementation may define extra domain errors to deal with floating-point arguments such as infinity or ``not-a-number''.
The Committee considered the adoption of the matherr
capability
from UNIX System V.
In this feature of that system's math library,
any error (such as overflow or underflow) results in a
call from the library function to a user-defined exception handler
named matherr
.
The Committee rejected this approach for several reasons:
matherr
),
which may complicate some implementations.
Implementation note: trignometric argument reduction should be performed by a method that causes no catastrophic discontinuities in the error of the computed result. In particular, methods based solely on naive application of a calculation like
x - (2*pi) * (int)(x/(2*pi))are ill-advised.
acos
function
asin
function
atan
function
atan2
function
The atan2
function is modelled after FORTRAN's.
It is described in terms of arctany/x for simplicity;
the Committee did not wish to complicate the descriptions by
specifying in detail how the determine the appropriate quadrant,
since that should be obvious from normal mathematical convention.
atan2(y,x)
is well-defined and finite, even when x
is 0;
the one ambiguity occurs when both arguments are 0, because at
that point any value in the range of the function could logically
be selected. Since valid reasons can be advanced for all the
different choices that have been in this situation by various
implements, the Standard preserves the implementor's freedom
to return an arbitrary well-defined value such as 0, to report
a domain error, or to return an IEEE NaN code.
cos
function
sin
function
tan
function
The tangent function has singularities at odd multiples of
pi/2,
approaching +infinity from one side and -infinity from the other.
Implementations commonly perform argument reduction using the best
machine representation of pi; for arguments to tan
sufficiently
close to a singularity, such reduction may yield a value on the
wrong side of the singularity.
In view of such problems, the Committee has recognized that tan
is an exception to the range error rule (§4.5.1)
that an overflowing result produces HUGE_VAL
properly signed.)
cosh
function
sinh
function
tanh
function
exp
function
frexp
function
The functions
frexp
, ldexp
, and modf
are primitives used by the
remainder of the library.
There was some sentiment for dropping them for the same reasons that
ecvt
, fcvt
, and gcvt
were dropped,
but their adherents rescued them for general use.
Their use is problematic: on nonbinary architectures ldexp
may lose precision, and frexp
may be inefficient.
ldexp
functionSee §4.5.4.2.
log
function
Whether log(0.)
is a domain error or a range error is arguable.
The choice in the Standard,
range error,
is for compatibility with IEEE P854.
Some such implementations would represent the result as -infinity,
in which case no error is raised.
log10
functionSee §4.5.4.4.
modf
functionSee §4.5.4.2.
pow
function
sqrt
function
IEEE P854, unlike the Standard, requires
sqrt(-0.)
to return a negatively signed magnitude-zero result.
This is an issue on implementations that support a negative floating zero.
The Standard specifies that taking the square root of a negative number
(in the mathematical sense: less than 0)
is a domain error which requires the
function to return an
implementation-defined value.
This rule permits implementations to support either the IEEE P854
or vendor-specific floating point representations.
ceil
function
Implementation note:
The ceil
function returns the smallest integral value in double
format not less than x
, even though that integer might not be
representable in a C integral type. ceil(x)
equals x
for
all x
sufficiently large in magnitude. An implementation that
calculates ceil(x)
as
(double)(int) xis ill-advised.
fabs
functionAdding an absolute value operator was rejected by the Committee. An implementation can provide a built-in function for efficiency.
floor
function
fmod
function
fmod
is defined even if the quotient x/y
is
not representable ---
this function is properly implemented
by scaled subtraction rather than by division.
The Standard defines the result in terms of the formula
x
-i*y
, where i is some integer. This integer need
not be representable, and need not even be explicitly computed.
Thus implementations are advised not to compute the result
using a formula like
x - y * (int)(x/y)Instead, the result can be computed in principle by subtracting
ldexp(y,n)
from x
, for appropriately chosen decreasing
n
, until the remainder is between 0 and x
--- efficiency
considerations may dictate a different actual implementation.
The result of fmod(x,0.0)
is either a domain error or 0.0;
the result always lies between 0.0 and y
,
so specifying the non-erroneous result as 0.0
simply recognizes the limit case.
The Committee considered and rejected a proposal to use the
remainder operator %
for this function;
the operators in general correspond to hardware facilities, and
fmod
is not supported in hardware on most machines.