Most programming environments provide the four rational functions:
add(x, y)
→ \( x + y \) sub(x, y)
→ \( x - y \) mul(x, y)
→ \( x \times y \) div(x, y)
→ \( x / y \) x * y
.
One powerful alternative is the s-expression
form (* x y)
of Scheme and Lisp.
There is even the postfix form of
Forth: x y *
.
IEEE Standard 754 defines several less obvious, but also useful functions:
sqrt(x)
→ \( \sqrt{x} \)remainder(x, y)
→ the (exact)
remainder left when the full integer value of \( x / y \)
is computed
nextUp(x)
→ smallest
y
with x < y
nextDown(x)
→ largest
y
with y < x
scaleB(x, n)
→
\( x \times 2^{n} \)
logB(x)
→ satisfies
1.0 <= scaleB(x, -logB(x)) < 2.0
copysign(x, y)
→ value y
with sign of x
abs(x)
→ x
with positive sign
neg(x)
→ x
with its sign reversed
Many programming environments have explicit integer data types. Converting to floating point from an integer type falls right into the pattern of any arithmetic operation. Converting from floating point to an integer type requires specification for values outside the range of integers, such as happens with huge values, \( \infty \), and NaN.
Converting between floating point and string formats depends on the environment. One of the attractions of decimal floating point is the lack of surprise converting between everyday decimal and internal decimal forms. Some environments support display in a radix other than decimal. These conversions usually appear in software that can handle the subtleties of formatting.
Any floating point system is going be a mix of hardware and software. The fastest systems are generally those with the most complete hardware support. But the conversation about floating point can be independent of how the features are implemented.
To fill out the discussion, here is the start of a bottomless list of floating point functions. Their implementation is usually in software. In the 1960s and 1970s, numerical software libraries were of highly variable quality. Since the arrival of IEEE 754, substantial effort has gone into refining these functions. Intel notably broke from convention by providing elementary function support on its 8087 and subsequent chips.
These common functions can be implemented in the same spirit as the carefully-specified arithmetic operations. Accuracy is another matter, as we will see.
pow(x, y)
→ \( x^{y} \)
log(x)
→ natural logarithm, or log base \( e \)
log1p(x)
→ \( log(1 + x) \),
without explicitly adding \( 1 + x \)
exp(x)
→ \( e^{x} \)
expm1(x)
→ \( e^{x} - 1 \),
without explicitly computing \( e^{x} \)
sin(x)
→ trigonometric sine
cos(x)
→ trigonometric cosine
tan(x)
→ trigonometric tangent
atan(x)
→ trigonometric arctangent
sinh(x)
→ hyperbolic sine
cosh(x)
→ hyperbolic cosine
tanh(x)
→ hyperbolic tangent
atanh(x)
→ hyperbolic arctangent
The subtleties of rounding the transcendental functions and performing trigonometric argument reduction modulo \( \pi / n \) are topics all their own, but we will touch on them here.