Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Division by zero prevention: Checking the divisor's expression doesn't result in zero vs. checking the divisor isn't zero?

Is division by zero possible in the following case due to the floating point error in the subtraction?

float x, y, z;
...
if (y != 1.0)
    z = x / (y - 1.0);

In other words, is the following any safer?

float divisor = y - 1.0;
if (divisor != 0.0)
    z = x / divisor;
like image 862
Max Avatar asked Oct 10 '12 17:10

Max


People also ask

What happens when you divide by zero in programming?

Dividing a number by Zero is a mathematical error (not defined) and we can use exception handling to gracefully overcome such operations. If you write a code without using exception handling then the output of division by zero will be shown as infinity which cannot be further processed.

What happens when you attempt a division by zero in C?

In languages like C, C++ etc. division by zero invokes undefined behaviour.

Which error will occur when dividing a number with zero?

Microsoft Excel shows the #DIV/0! error when a number is divided by zero (0). It happens when you enter a simple formula like =5/0, or when a formula refers to a cell that has 0 or is blank, as shown in this picture.

Why is a division by zero undefined?

The reason, in short, is that whatever we may answer, we will then have to agree that that answer times 0 equals to 1, and that cannot be ​true, because anything times 0 is 0.


3 Answers

Assuming IEEE-754 floating-point, they are equivalent.

It is a basic theorem of FP arithmetic that for finite x and y, x - y == 0 if and only if x == y, assuming gradual underflow.

If subnormal results are flushed to zero (instead of gradual underflow), this theorem holds only if the result x - y is normal. Because 1.0 is well scaled, y - 1.0 is never subnormal, and so y - 1.0 is zero if and only if y is exactly 1.0, regardless of how underflow are handled.

C++ doesn't guarantee IEEE-754, of course, but the theorem is true for most "reasonable" floating-point systems.

like image 67
Stephen Canon Avatar answered Oct 16 '22 19:10

Stephen Canon


This will prevent you from dividing by exactly zero, however that does not mean still won't end up with +/-inf as a result. The denominator could still be small enough so that the answer is not representable with a double and you will end up with an inf. For example:

#include <iostream>
#include <limits>

int main(int argc, char const *argv[])
{
    double small = std::numeric_limits<double>::epsilon();
    double large = std::numeric_limits<double>::max() / small;
    std::cout << "small: " << small << std::endl;
    std::cout << "large: " << large << std::endl;
    return 0;
}

In this program small is non-zero, but it is so small that large exceeds the range of double and is inf.

like image 27
David Brown Avatar answered Oct 16 '22 20:10

David Brown


There is no difference between the two code snippets () - in fact, the optimizer could even optimize both fragments to the same binary code, assuming that there are no further uses of the divisor variable.

Note, however, that division by a floating point zero 0.0 does not result in a run-time error, but produces an inf or -inf instead.

like image 2
Sergey Kalinichenko Avatar answered Oct 16 '22 19:10

Sergey Kalinichenko