[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.

754 | revision | FAQ | references | list archive