tings said:
An article states: "In floating point maths, where if you divide by a
sufficiently large number sufficiently often, you will always be able to
reach a value too small to distinguish from zero, given the finite precision
you have."
You can't be sure that dividing by just a large number will do
that though. There will be lots of single numbers you could divide by
to get underflow, and after all...
(a/b)/c = a/(b*c)
It would take more work to find the number of least magnitude
that you could pick... in any case, it's just a way of stating it.
It's the same if you divide numbers that aren't so large,
enough times it will eventually happen that you get underflow.
If all you are doing is divisions by numbers whose magnitude is
big, then it's going to be the end result if you performed
just enough of these divisions [by themselves].
What does it mean "sufficiently often" since only one division should be
enough to cause underflow in division between two floating point numbers?
I believe an underlying assumption is that you are performing
other operations and keeping a cumulative result, you are not
just dividing but performing a computation that involves systematic
application of something else, perhaps many operations (additions,
multiplications, or subtractions) as well as divisions.
So "often" is characterizing at what rate you are dividing your
current result by a large number which diminishes its magnitude
compared to operations that will amplify its magnitude in getting
your next result.
Being sufficiently often means that your divisions are not so
scattered or interleaved with other operations that increase
in magnitude that you stay away from zero.
i.e. if you had
double value = 500;
for(i = 0; i < 10000; i++) {
value = value * 100 - 1;
value = value / 100;
}
You will certainly be performing many divisions, but 'value'
will probably never be so close as to be rounded to 0.
Only about 1/3 of your operations are divisions, and 1/3 of your
operations increase value in number.
So the divisions were probably not often enough.
Now if you did
for(i = 0; i < 10000; i++) {
value = value * 100 + 1;
for(k = 0; k < 10; k++) { value = value / 100; }
}
You might find that to be dividing sufficiently often.
When underflow happens, the result of the above division should be regarded
as "undefined behavior"? In other words, the result could be any floating
number or just a meanless "number." Is this correct?
It depends on the nature of what you are doing. In some case it
could be suggesting a possibility that you lost precision or
something blew up, but...
I wouldn't generalize that, IMO.. you need to evaluate whether the
result fits your expectations and is the right thing to get or if
the underflow is making a mess and you need to get a higher precision
or perform the computations differently.
I don't know of any hard and fast rule.
-Mysid