Is it possible to get division by 0 (or infinity) in the following example?
public double calculation(double a, double b)
{
if (a == b)
{
return 0;
}
else
{
return 2 / (a - b);
}
}
In normal cases it will not, of course. But what if a
and b
are very close, can (a-b)
result in being 0
due to precision of the calculation?
Note that this question is for Java, but I think it will apply to most programming languages.
As a workaround, what about the following?
That way you don't depend on IEEE support in any language.
The supplied function can indeed return infinity:
The output is
Result: -Infinity
.When the result of the division is to big to be stored in a double, infinity is returned even if the denominator is non-zero.
You shouldn't ever compare floats or doubles for equality; because, you can't really guarantee that the number you assign to the float or double is exact.
To compare floats for equality sanely, you need to check if the value is "close enough" to the same value:
There is no case where a division by zero can happen here.
The SMT Solver Z3 supports precise IEEE floating point arithmetic. Let's ask Z3 to find numbers
a
andb
such thata != b && (a - b) == 0
:The result is
UNSAT
. There are no such numbers.The above SMTLIB string also allows Z3 to pick an arbitrary rounding mode (
rm
). This means that the result holds for all possible rounding modes (of which there are five). The result also includes the possibility that any of the variables in play might beNaN
or infinity.a == b
is implemented asfp.eq
quality so that+0f
and-0f
compare equal. The comparison with zero is implemented usingfp.eq
as well. Since the question is aimed at avoiding a division by zero this is the appropriate comparison.If the equality test was implemented using bitwise equality,
+0f
and-0f
would have been a way to makea - b
zero. An incorrect previous version of this answer contains mode details about that case for the curious.Z3 Online does not yet support the FPA theory. This result was obtained using the latest unstable branch. It can be reproduced using the .NET bindings as follows:
Using Z3 to answer IEEE float questions is nice because it is hard to overlook cases (such as
NaN
,-0f
,+-inf
) and you can ask arbitrary questions. No need to interpret and cite specifications. You can even ask mixed float and integer questions such as "is this particularint log2(float)
algorithm correct?".I can think of a case where you might be able to cause this to happen. Here's an analogous sample in base 10 - really, this would happen in base 2, of course.
Floating point numbers are stored more or less in scientific notation - that is, instead of seeing 35.2, the number being stored would be more like 3.52e2.
Imagine for the sake of convenience that we have a floating point unit that operates in base 10 and has 3 digits of accuracy. What happens when you subtract 9.99 from 10.0?
1.00e2-9.99e1
Shift to give each value the same exponent
1.00e2-0.999e2
Round to 3 digits
1.00e2-1.00e2
Uh oh!
Whether this can happen ultimately depends on the FPU design. Since the range of exponents for a double is very large, the hardware has to round internally at some point, but in the case above, just 1 extra digit internally will prevent any problem.
Division by zero is undefined, since the limit from positive numbers tend to infinity, the limited from negative numbers tend to negative infinity.
Not sure if this is C++ or Java since there is no language tag.