In your sample document, you are rounding the result of subtraction to the position of 15th decimal digit of the greater of the original values. So your idea is to limit the precision of calculation to “fix” catastrophic cancellation.
Your idea is not new; also it is not correct. Your idea is about assumption that what is displayed in cell is closer to “ideal” value than what is actually there. It might be true only with very limited set of cases, where the values in cells are manually typed there by user, and only addition/subtracted is used.
But it would make most real calculations worse. Consider any trigonometric functions where you use radians, or any logarithmic functions, or even simple multiplication/division. There you get more “significant” digits than were in initial numbers that user had entered. And arbitrarily limiting the precision of those numbers would result in much worse catastrophes universally.
For instance, take this simple calculation of well-known triangle and its scaled variant:
A B
1 3 =A1*PI()
2 4 =A2*PI()
3 5 =A3*PI()
4 =SQRT(A3^2-A2^2) =SQRT(B3^2-B2^2)
In ideal world, A4
must be equal to A1
, and B4
to B1
. In Calc, although the value of PI()
is naturally imperfect, RAWSUBTRACT(B1;B4)
also shows 0
. But if in B4
we replace SQRT(B3^2-B2^2)
with your SQRT(ROUND(RAWSUBTRACT(B3^2;B2^2);15-MAX(ROUND(LOG(ABS(B3^2);10);0);ROUND(LOG(ABS(B2^2);10);0))))
, we suddenly get the difference between B1
and B4
by 1.77635683940025E-15
.
Carefully prepared limited-precision input in your sample is not representative. Note that I don’t talk about performance here, I only talk about precision that you try to achieve. Your approach would fail miserably in all but simplest cases. Current implementation of subtract is of course not ideal (in this non-ideal world), but you may notice that it still tries to be reasonably smart using rtl::math::approxSub
which handles near-zero result (unlike the implementation of RAWSUBTRACT, which tries to be simple).