[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
Re: Suggestion of annex D
Peter,
Peter Henderson wrote on 28.05.2007 16:08:
Florent,
your proposal looks good to me, but you need to address the problem of
when the limit is zero. I have put a rough suggestion at the end of
this reply. Also a principle for -0 is required when the domain does
not include negative values. These two items are the main reason for
this reply.
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.
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 covers the following cases:
* sqrt(0) = 0 => sqrt(-0) = -0
* expm1(0) = 0 => expm1(-0) = -0
* log(eps) -> +infty for eps -> 0, eps > 0 => log(+0) = -infty
* log(eps) undefined for eps < 0, even infinitesimal => log(-0) = NaN
Actually, this already answers your main concern below.
[...]
For example, concerning pow, there is a consensus among the
mathematicians that 0^0=1 is convenient.
Which makes a general rule more general, hence less fiddly and likely to
lead to errors.
There is no such consensus on 0^infty, 1^infty, etc.
Actually, 0^infty should equal 0, by the limiting principle you describe
below. Perhaps you meant infty^0. In this case almost identical
arguments can be used justify infty^0 = 1.
So much the better for 0^infty, where the principle defines that the
operation pow return 0.
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
The previous function is undefined there.
.
.
.
Once this clarification is made, the second idea in this suggestion is
that the operation returns NaN for any input on which the function is
undefined. This is the easy consistent option, but it differs from the
C99 standard.
Disagreeing with the C standard, or any other standard for that matter
is the correct choice when they specify bad choices. The result will be
that users will have the choice of the mor econsidered ieee 754 function
or an inferior version.
I have only seen the draft C standard, but its suggestion for pow(x,y)
does not inspire confidence. My main objection is that it should be
split into two functions, one taking integer exponents and the second
taking real exponents, but only applying them to non-negative numbers.
.
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.
.
.
Now to the main purpose of my reply.
For an n-ary function f and floating-point numbers X1,..Xn,
when the limit of f(x1,...xn) as (x1,...xn) tends to (X1,..Xn) exists
and is a real number c , the operation associated to f(X1,...Xn) shall
return c rounded in the prevailing rounding mode. When this limit is
an infinity, the operation shall return this infinity. When this limit
does not exist, (X1,..Xn) shall be considered as an invalid operand.
In the case when one of the Xi is +0 (resp. -0), the limit shall be
considered using positive (resp. negative) values only of the
corresponding xi.
]
Do you intend this applies to all limit points, i.e. not just to those
involving infinity? I think this is the correct choice, but then you
must consider discontinuities, the most common of which are branch
points. These cases would always require special consideration.
Fortunately, there is a strong consensus for most branch points. Just
as fortunately, the consensus is usually covered by the cases of the
type x tends to +0 and x tends to -0.
I am not quite sure what you understand by branch points. Our proposal
intends to handle all discontinuities. "False" discontinuities, i.e.
points where the function can be extended by continuity give unique
limits. Discontinuities where f(x) tends to +/-infty are handled in the
affinely extended real numbers with limits +infty or -infty. Otherwise
the function is discontinuous at a point and the operation should return
NaN.
Nevertheless, our proposal is to include piecewise definitions of
functions, such as
f : R^2 -> R,
| (x,y) -> 1 if (x,y) = (0,0)
| (x,y) -> x^y
The case when the limit is zero needs to be dealt with. What is needed
is something like:
when the limit at (X1, ..., Xn) is 0, then if f(x1,...xn) >= 0 in a
region around (X1, ... , Xn), then a value of +0 should be returned,
otherwise if it is <= 0 in a region around (X1, ... , Xn), then -0
should be returned, otherwise +0 should be returned. This suggestion
has a bias towards +0, i.e. if f(x1, ... , xn) is identically zero
around (X1, ... , Xn), then return +0 and if f(x1, ... , xn) returns
both strictly positive and strictly negative values as it approaches
arbitrarily close to (X1, .. Xn), return +0. In the first of these
cases, -0 would be preferable if the function is < 0 immediately outside
the region where it is identically zero.
I am okay with an explicite indication in the standard for this case.
Another important case is when the limit as x tends to zero is zero, for
a function which is undefined for x < 0. My strong preference is that
f(-0) should equal f(+0) equals f(zero). I am using "zero" to indicate
the mathematical value, as opposed to the floating point constructs
=/-0. However, the only example in the standard of this case I can see
is sqrt(), in which case sqrt(-0) is specified to be -0. I do not know
the justification for this choice, but is seems problematical, as
-infty's can turn up unexpectedly where programmers would assume they
can only get positive values.
I am okay with your objection to sqrt(-0) = -0 but I don't think people
are willing to change the behaviour of one of the 5 basic operations in
the old standard.
That's why I propose to have:
+0 = -0 = zero
If f(zero) = zero and x = zero then f(x) = x.
Otherwise, if f(zero) is not finite, apply the infinity arithmetic proposal.
Christoph Lauter