[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
Re: Zeroes and infinities
Thorsten Siebenborn wrote:
.
.
.
But IEEE 754 does, because in many cases it can be used to produce
useful results, for example the straight-forward, fast and highly
accurate evaluation of continued fractions,
Why highly accurate ?
The continued fraction should be (b[0],b[1],....);
If the denominator of a continued fraction containing the constant
b[i] equals 0.0, all former calculations of higher b[i]s will be lost
and the result will be equivalent to (b0,b1,....,b[i-2]). It will
simulate a result of greater accuracy when in fact it stagnates.
If the programmer calculate them with ever increasing precision, he
will probably encounter strange discontinuties (when the denomiator
hits zero).
Certainly, in the case the function being approximated is finite, this
is precisely what is required. In exact arithmetic this stagnation
gives the exact answer. Consider a[0]
/(b[0]+a[1]*x/(.../(b[n]+f(x))...)), where f(x) is the result of the
terms beyond b[n]. As f(x) approaches -b[n], at y say, the term t[n]
= b[n]+f(x) goes to zero. As a result, the term t[n-1] =
b[n-1]+a[n-1]*x/(b[n]+f(x)) goes to infinity and the term above,
b[n-2]+a[n-2]*x/t[n-1] goes to b[n-2]. Hence the whole expression
tends to a[0]/(b[0]+a[1]*x/(.../b[n-2]...). Once a[n-2]*x/t[n-1] is
much smaller than b[n-2], i.e. we assume b[n-2] != 0, the function
varies slowly in the vicinity of y. For the case where the limit of
the function at y is finite, round-off error and truncation error will
shift the location at which f(x) equals zero and may cause signs to
change erroneously, but this will effect the evaluation of the
function at y hardly at all. So using 1/0 = infinity and 1/infinity =
0 gives the answer required.
This analysis can be derailed if two such points occur too close
together, but this is no different to the cases where roots of
polynomials or eignevalues of matrices are too close together. The
behaviour at points where the function tends to +infinity from both
sides (similarly for -infinity) is trickier and can go wrong as
inadvertant sign changes in f(x) will lead to the wrong sign for the
resulting infinity. However, this is all part of selecting the
correct approach to the problem.
.
.
.
I am a programmer. I have never ever checked if the result of a
division is +-Infinity. In fact, I always avoid infinities,
division by zero and NaNs like the pest.
But this is not always possible, and can lead to code that runs much
slower than necessary. I had a problem processing large data sets
where some sets would generate an overflow and hence a core dump, may
be after a day or two of computation, after which, the offending data
set was discarded, and the calculation restarted. The machine I was
using did not use IEEE arithmetic by default, turning it on caused a
roughly 6 times degradation in performance. Trying to detect the
overflow condition before it occurred proved frustrating and all but
impossible. The solution was to implement extended exponent floating
point numbers, with continuous rescaling of the the results of
floating point operations. It would have been far simpler to let the
calculation for a data set tun to completion and check for infinity or
NaN at the end.
.
.
.
And this is the reason I prefer trapping instead of substituition
values.
But most programming languages provide poor and rudimentary facilities
for writing trap handlers.
I think you have understand my hint ;-). Concerning 0/0 I don't see it
as a NaN, but as an indeterminate expression which has a limit value
and can therefore be fixed (like the sinc function).
Yes, often a meaningful result can be given when 0/0 occurs, but no
universally applicable result can be defined. That is why NaN is the
proper result to return. It indicates a special case has occurred
that must be attended to.
.
.
.
Now the hardware thing: A trap is nothing else than an interrupt
caused by the FP unit, normally on IRQ channel 13 on the 80x86.
The interrupt handler is called (leaving the current state
unchanged), executing code and returning with IRET.
As *all* hardware is communicating with the processor in this
Michael Hack's response addressed this.
way I would be very astonished that there would be a remarkable
performance penalty.
But there is. Problems occur with deep pipelines and parallel
execution. Errors such as divide by zero and invalid operations are
usually detected when the operands enter the pipeline, while overflows
cannot be detected until the end. Hence instructions may need to be
aborted or unwound and pipelines flushed. When a trap is activated,
this invariabably requires the pipeline to be flushed first. Another
example are the parallel SSE instructions on the Pentium. The
recommended procedure for handling a trap is to redo all four
calculations using the scalar floating-point unit. As a result, not
turning on trap handling and checking for infinties or NaN's
afterwards can be much faster, as this can be done within the normal
flow of the program.
What language are you using ? And can you send me some source
code of you to see how you are handling IEEE 754 ?
C or C++. In fact most of the time I just do as you do, try and avoid
overflow if possible. My example above is from a while ago, but it
illustrates my point. Sometimes it just becomes extremely difficult
and expensive to avoid overflow. Having to continuely rescale cancels
out the benefits floating point.
.
.
.
That is really a nice theory that neg zero could be always
safely ignored.
Well, let's imagine the following situation: You have a GPS routine
giving you back the degrees, the minutes and the seconds in a double
array. Mind you, minutes and seconds are always positive.
HMS Titanic II approaches the equator and the autopilot
is on. What happens if the steering routine ignores the sign ?
If the sign is attached to zero, then it should not matter. On the
other hand using the sign of zero creatively may be the best way to
deal with gimball lock. I am yet to see a result where ignoring the
sign of zero actually causes a problem. The situations where I can
see it causing a problem are more the limiting cases of rounding error
causing a problem, in particular causing an unexpected change of sign
in a small result. But in these cases, the issue isn't really the
sign of zero, it is loss of all precision due to underflow or
round-off.
Regards,
Peter Henderson