I have a calculation using double
and run into problems due to catastrophic cancellation (nearly equal values are subtracted). I am looking for a rearrangement to keep the loss of significance at a minimum.
My equation is that of a plane from which I compute z = z(x, y)
(with a set of constants z0, x21, ...
):
// (z-z0)*(x21*y31 - y21*x31) = (x-x0)*(y21*z31 - z21*y31) + (y-y0)*(z21*x31-x21*z31)
double z = z0 + (x-x0)*(y21*z31 - z21*y31)/(x21*y31 - y21*x31)
+ (y-y0)*(z21*x31-x21*z31)/(x21*y31 - y21*x31);
One set of values for which I run into problems is given below. In this case it is due to y-terms all being close to zero (y21 ~= -0.0032, y31 ~= -0.0097, y-y0 ~= -0.0032
):
(z-z0) * 9.3241e-18 ~= 0.1112*0.0830 + (-0.0032)*2.8428
~= 0.009234 - 0.009234
~= 5.2042e-18
The result is barely usable since I suspect both 9.3241e-18
and 5.2042e-18
to be affected by calculation errors.
I am looking for a way to deal with calculation errors due to subtraction in general and a smart rearrangement for the special case of y21, y31, y-y0
being close to zero in particular. The rearrangement I tried have not had success so far. How can I deal with those calculation problems (in C++).