 # Can Chapel catch division by zero?

Hi! I am trying to catch a division by zero error:

``````var zf: real;
try {
zf = zminop  - Aminop/dAlop(zminop);
}
catch {
zf = zminop;
}
``````

where dAlop(zminop) returns 0.0, but it does not seem to work. I wonder if it is possible at present to catch floating point exceptions? Any suggestions welcome! Thanks,

Nelson

Hi Nelson,

For me the computation `zf = zminop - Aminop/dAlop(zminop);` completes successfully, producing `-inf`. Would this work for you if you checked for it using `isinf` and/or `isnan` ?

We currently do not have exceptions for arithmetic operations, and even if we did, exceptions might add noticeable performance overhead.

Vass

Hi Vass: thanks for the answer. I imagined that performance could be an issue. My program runs and gives -inf for zf. Of course, an old-fashioned if (or isinf, or isnan) solves the issue, so I will use it.

regards

Nelson

You do not need to be that extreme, nor sacrifice too much performance. If what you describe is all you are trying to do, there are alternatives. Note that the invocation of isinf() or isnan() as they are currently implemented in many libraries include a mandatory memory access.

The code to test whether x is +INFINITY or -INFINITY is

``````if abs(x) == INFINITY then // pretty obvious
``````

The code to test whether some number is a Not-A-Number or NaN is

``````if x != x then // only happens with x is actually an NaN
``````

The above on the other hand, will only incur the penalty of a floating point comparison.

Try this

``````type Real = real(32);
const zero = 0:Real;
const inf = INFINITY:Real;
const one = 1:Real;
const t = one / zero;
const z = (zero - zero) / (zero - zero);

writeln("comparing against INFINITY ", if t == inf then "works" else "fails");
writeln("verifying real(w) is a NAN ", if z != z then "works" else "fails");
``````

If you really want to be extravagant, you can start looking for IEEE 754 exceptions which are very different animals to a Chapel (or C++) exception. And they may have all sorts of optimization issues because Chapel does not honour statement sequence when producing code.

I compile with --fast and follow that by --ieee-float to make sure the compiler does think that the comparison of a number against itself will ever fail (which some dumb optimizer might assume).

None of the above codes introduces superfluous IEEE754 exceptions.

Looking at your code, if the term

``````Aminop/dAlop(zminop)
``````

blows up, i.e. goes to INFINITY, you want to throw it away. Would

``````zf = zminop - let t = Aminop/dAlop(zminop) in if abs(t) != INFINITY then t else 0:t.type;
``````

achieve the same result?

Hi Damian: thanks for the suggestion.

I had settled with the rather orthodox
if dAlop(zminop) == 0.0 then {
zf = zminop;
}
else {
zf = zminop - Aminop/dAlop(zminop);
}

The alternative you proposed
zf = zminop - let
t = Aminop/dAlop(zminop) in
if abs(t) != INFINITY then t else 0.0;

seems to produce the same results. Apart from the fact that I am calling a function twice in the first alternative, and that this could of course be avoided, an if is still needed in both options, so I wonder if the second has an advantage in performance.

Regards

Nelson

Your solution does not catch the case where the function is much much smaller than Aminop and the division still yields INFINITY. Unless of course you want zf to really be set to -INFINITY

In answer to your question after performance, I would always avoid two function calls when I can do the same calculation with one. Period!