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,
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.
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.
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.
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.
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!