Search code examples
c++numericfractions

Simplify fractions at compile time to avoid division by zero


Is there a way to simplify fractions prior to evaluation in order to avoid division by zero?

Example:

double x1 = 2;
double x2 = 2;
double x3 = 2;

double r1 = (x1-x2)/(x1-x2-x3);
cout << r1 << endl;
x3 = 0;
r1 = (x1-x2)/(x1-x2-x3);
cout << r1 << endl;

will return:

-0
-nan

Is it possible to make the compiler simplify the second expression at compile time to avoid the division by zero? In particular, if x3 equals 0, I expect (x1-x2)/(x1-x2-x3) to be simplified to 1.

In my code the factors x1, x2 and x3 are replaced by functions.


Solution

  • I already stated the following in comments (that maybe sounded a bit rude, but thats just because I think it is really important to clear up this misunderstanding): You cannot avoid division by zero by simply rearranging the fraction or doing cancellations. To see why is this, consider this example:

     x/y
    

    This is not the same as

     (0*x) / (0*y)
    

    because this changes the value of the fraction considerably. In general

     x/y = (a*x) / (a*y)
    

    is true, only if a is not 0. Another way to see this is by considering equations and possible transformations. Consider

    a = b
    

    this is definitely not the same as

    0*a = 0*b
    

    but

    (a = b)  is equivalent to (a*x = b*x) 
    

    only holds if x is not 0.

    If you want to avoid division by zero, the only way is to check if the divisor is 0 and handle this case in some way. You cannot avoid division by zero by canceling out the 0, because this will change the value of the fraction.