xref: /csrg-svn/lib/libm/common_source/ieee.3 (revision 24373)
IEEE 3M "7 August 1985"
C 4
NAME
copysign, drem, finite, logb, scalb - copysign, remainder, exponent manipulations
SYNOPSIS
 #include <math.h> 

double copysign(x,y) double x,y;

double drem(x,y) double x,y;

int finite(x) double x;

double logb(x) double x;

double scalb(x,n) double x; int n;

DESCRIPTION
These functions are required for, or recommended by the IEEE standard 754 for floating-point arithmetic.

Copysign(x,y) returns x with its sign changed to y's.

Drem(x,y) returns the remainder r := x - n\(**y where n is the integer nearest the exact value of x/y; moreover if |n\|-\|x/y|\|=\|1/2 then n is even. Consequently the remainder is computed exactly and |r| \(<= |y|/2. But drem(x,0) is exceptional; see below under DIAGNOSTICS.

Finite(x) = 1 just when -infinity < x < +infinity,
Finite(x) = 1 just when -\(if < x < +\(if,
 = 0 otherwise (when |x| = infinity or x is \*(nn or
 = 0 otherwise (when |x| = \(if or x is \*(nn or
 \0x is the VAX's reserved operand.)

Logb(x) returns x's exponent n, a signed integer converted to double-precision floating-point and so chosen that 1\0\(<=\0|x|/2**n\0<\02 unless x = 0 or (only on machines that conform to IEEE 754) |x| = infinity |x| = \(if or x lies between 0 and the Underflow Threshold; see below under "BUGS".

Scalb(x,n) = x\(**(2**n) computed, for integer n, without first computing 2**n.

SEE ALSO
intro(3M), infnan(3M)
DIAGNOSTICS
IEEE 754 defines drem(x,0) and drem(infinity,y) drem(\(if,y) to be invalid operations that produce a \*(nn. On a VAX, drem(x,0) returns the reserved operand. No infinity \(if exists on a VAX.

IEEE 754 defines logb(\(+-infinity) = +infinity and logb(0) = -infinity, logb(\(+-\(if) = +\(if and logb(0) = -\(if, and requires the latter to signal Division-by-Zero. But on a VAX, logb(0) = 1.0 - 2.0**31 = -2,147,483,647.0. And if the correct value of scalb(x,n) would overflow on a VAX, it returns the reserved operand and sets errno to ERANGE.

AUTHOR
Kwok-Choi Ng
BUGS
Should drem(x,0) and logb(0) on a VAX signal invalidity by setting errno = EDOM? Should logb(0) return -1.7e38?

IEEE 754 currently specifies that logb(denormalized no.) = logb(tiniest normalized no. > 0) but the consensus has changed to the specification in the new proposed IEEE standard p854, namely that logb(x) satisfy

1 \(<= scalb(|x|,-logb(x)) < Radix\0\0\0... = 2 for IEEE 754

for every x except 0, infinity \(if and \*(nn. Almost every program that assumes 754's specification will work correctly if logb follows 854's specification instead.

IEEE 754 requires copysign(x,\*(nn) = \(+-x but says nothing else about the sign of a \*(nn. A \*(nn (Not a Number) is similar in spirit to the VAX's reserved operand, but very different in important details. Since the sign bit of a reserved operand makes it look negative,

copysign(x,reserved operand) = -x;

should this return the reserved operand instead?