[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
Re: Suggestion of annex D
Christoph Quirin Lauter wrote:
I am okay with that. We (Florent and I) thought to have treated the
question as follows: +0 = 0 = -0 and for functions for which f(0) is
some finite c, the operation f(-0) returns c. If c is 0, then f(-0) is
-0.
The principle I was using in my rules for f(y) = 0, where y can be
anything except NaN, and if y=-0, we consider the limit as x tends to
zero from below and if y=+0, we consider the limit as x tends to zero
from above is this: If f(x) tends to zero from above, then f(y) = +0
and if f(y) tends to zero from below f(y)=-0. In this manner 1/f(y) is
the limit of 1/f(x) as x tends to y. This is the behaviour you will see
if you evaluate 1.0/((x+1)*(x+1)) in the obvious way as x tends to -1.0,
i.e. this behaviour is consistent with the behaviour of the arithmetic
system.
These rules do not work if f(x) is 0 in a region and y is in the
interior of this region. In this case the choice is unlikely to be
important, as one has no business evaluating 1/f(x) in such a region.
Of course, for reasons of taste, one would strongly prefer the sign of
zero to agree with the sign of f(x) immediatley around the region where
it is zero, if only one sign occurs. i.e. If f(x) is 0 in a region and
f(x) < 0 around this region, f(y) = -0 for y in the region. Similary
f(y) = +0 if f(x) > 0 around the region. The topological requirements
need to be more rigorously expressed here, but I think the intent is
clear. If both signs occur on the around the boundaries of the region
{x: f(x) = 0}, then it may be possible to tastefully divide the region
between +0 and -0. Perhaps based on symmetry considerations.
Otherwise, choose +0, as the x-x=+0 rule in the standard suggests a
slight preference for +0 when the result is an exact zero.
They also do not work if f(x) tends to zero from both above and below,
then +0 is preferable, due to the bias mentioned above, but again the
choice is not really important.
In cases where f(0) is not a finite c, infinity arithmetic rules
apply, i.e. +0 is considered as a infinitesimally small positive
number, -0 as a infinitesimally small negative number. (cf. our
proposal for section 7.1 of the draft)
This view of +0 and -0 cannot be made to work. The philosophy of the
standard is that a number represents itself. +0 and -0 both represent
the number zero. The sign is more like a flag, indicating something
about the manner in which zero was arrived at. In the arithmetic, this
usually relates to whether it was through rounding from below or above
zero, or exactly through x/(+/-inf). The rule x-x=+0 is the other exact
way of arriving at zero, which suggests a slight bias towards +0. The
propagation rules and zero's interaction with the infinities justify the
rules I described above, and I have know doubt this was one of the
intentions for those propagation rules.
This covers the following cases:
* sqrt(0) = 0 => sqrt(-0) = -0
As I mentioned, I had a strong preference for sqrt(-0) = -0, but of
course it can't be changed now.
* expm1(0) = 0 => expm1(-0) = -0
This is only appropriate because the derivative is > 0 at 0. Also, this
should be expm1(+0) = +0.
* log(eps) -> +infty for eps -> 0, eps > 0 => log(+0) = -infty
Actually, log(eps) is finite for any finite floating point number > 0.
log(+0)= -infty, as this is the limit as x tends to zero.
* log(eps) undefined for eps < 0, even infinitesimal => log(-0) = NaN
In a similar manner, sqrt(-0) = NaN, but it isn't, it is -0. I very
much prefer log(-0) = -inf. I do not think many programmers would be
pleased to performn the check x>= 0 and then get hit with a NaN. The
difficulty is I do not know the justification for sqrt(-0)=-0, the only
example of this situation we have in the standard.
For infty^0, the following can be said: for a given c, take
x(t) = 2^t -> infty for t -> infty
y(t) = log2(c)/t -> 0 for t -> infty
x(t)^y(t) = 2^(y(t) * log2(x(t))) = 2^(log2(c)/t * t) = c forall t
So the principle shows that the operation pow should return NaN
As I stated, the principled view is infty^0 returns NaN. But then, so
should 0^0. For all four exceptional cases of pow(x,y), a path can be
chosen to obtain any limit in [0, infty]. For 0^0, if x(t) and y(t)
both tend to zero as t tends to zero, and both are analytic about zero
and are not identically zero, then the limit is 1. For infty^0, the
same applies if x(t) has a Laurent series about zero. The main
attraction of 0^0 =1 is it makes the rule x^0 universal. My point is
that any argument for 0^0=1 applies for infty^0=1. The fact that
pow(1/x,y) = 1/pow(x,y), means these points are in a sense, mirror
images of each other.
Splitting pow into two functions is easy with our proposal: the
standard merly defines principles how operations should be
implemented. It is possible to define two mathematical functions with
different behaviour and to implement operations for them.
This is very much what I would encourage.