4.3BSD/usr/man/man3/ieee.3m

.\" Copyright (c) 1985 Regents of the University of California.
.\" All rights reserved.  The Berkeley software License Agreement
.\" specifies the terms and conditions for redistribution.
.\"
.\"	@(#)ieee.3m	6.2 (Berkeley) 5/12/86
.\"
.TH IEEE 3M  "May 12, 1986"
.UC 6
.ds nn \fINaN\fR
.SH NAME
copysign, drem, finite, logb, scalb \- copysign, remainder,
exponent manipulations
.SH SYNOPSIS
.nf
.B #include <math.h>
.PP
.B double copysign(x,y)
.B double x,y;
.PP
.B double drem(x,y)
.B double x,y;
.PP
.B int finite(x)
.B double x;
.PP
.B double logb(x)
.B double x;
.PP
.B double scalb(x,n)
.B double x;
.B int n;
.fi
.SH DESCRIPTION
These functions are required for, or recommended by the IEEE standard
754 for floating\-point arithmetic.
.PP
Copysign(x,y)
returns x with its sign changed to y's.
.PP
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.
.PP
.nf
.ta \w'Finite(x)'u+1n +\w'= 0 otherwise'u+1n
.if n \
Finite(x)	= 1 just when \-infinity < x < +infinity,
.if t \
Finite(x)	= 1 just when \-\(if < x < +\(if,
.if n \
	= 0 otherwise	(when |x| = infinity or x is \*(nn or
.if t \
	= 0 otherwise	(when |x| = \(if or x is \*(nn or
		\0x is the VAX's reserved operand.)
.ta
.fi
.PP
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)
.if n \
|x| = infinity
.if t \
|x| = \(if
or x lies between 0 and the Underflow Threshold; see below under "BUGS".
.PP
Scalb(x,n) = x\(**(2**n) computed, for integer n, without first computing
2**n.
.SH DIAGNOSTICS
IEEE 754 defines drem(x,0) and
.if n \
drem(infinity,y)
.if t \
drem(\(if,y)
to be invalid operations that produce a \*(nn.
On a VAX, drem(x,0) returns the reserved operand.  No
.if n \
infinity
.if t \
\(if
exists on a VAX.
.PP
IEEE 754 defines
.if n \
logb(\(+-infinity) = +infinity and logb(0) = \-infinity,
.if t \
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 \fIerrno\fR to ERANGE.
.SH SEE ALSO
floor(3M), math(3M), infnan(3M)
.SH AUTHOR
Kwok\-Choi Ng
.SH BUGS
Should drem(x,0) and logb(0) on a VAX signal invalidity 
by setting \fIerrno\fR = EDOM?  Should  logb(0) return  \-1.7e38?
.PP
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 
.RS
1 \(<= scalb(|x|,\-logb(x)) < Radix\0\0\0... = 2 for IEEE 754
.RE
for every x except 0, 
.if n \
infinity
.if t \
\(if
and \*(nn.
Almost every program that assumes 754's specification will work
correctly if logb follows 854's specification instead.
.PP
IEEE 754 requires copysign(x,\*(nn) = \(+-x  but says nothing
else about the sign of a \*(nn.  A \*(nn (\fIN\fRot \fIa\fR \fIN\fRumber) 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,  
.RS
copysign(x,reserved operand) = \-x;
.RE
should this return the reserved operand instead?