4.4 Localization ANSI C Rationale 4.6 Nonlocal jumps                    Index

# 4.5Mathematics <math.h>

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.

## 4.5.1Treatment of error conditions

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:

• This style is incompatible with popular floating point implementations, such as IEEE 754 (with its special return codes), or that of VAX/VMS
• It conflicts with the error-handling style of FORTRAN, thus making it more difficult to translate useful bodies of mathematical code from that language to C.
• It requires the math library to be reentrant (since math routines could be called from `matherr`), which may complicate some implementations.
• It introduces a new style of library interface: a user-defined library function with a library-defined name.  Note, by way of comparison, the signal and exit handling mechanisms, which provide a way of ``registering''  user-defined functions.

## 4.5.2Trigonometric functions

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))
```

## 4.5.2.4The `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.

## 4.5.2.7The `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.)

## 4.5.4.2The `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.

See §4.5.4.2

## 4.5.4.4The `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.

See §4.5.4.4

See §4.5.4.2

## 4.5.5.2The `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.

## 4.5.6.1The `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) x
```

## 4.5.6.2The `fabs` function

Adding an absolute value operator was rejected by the Committee.  An implementation can provide a built-in function for efficiency.

## 4.5.6.4The `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.

4.4 Localization ANSI C Rationale 4.6 Nonlocal jumps                    Index