Assume you want to know the first W
significant digits of a number, say pi, using vpa
. Simply calling vpa
with that many digits does not work. Consider the following example with W = 35
:
>> disp(vpa(sym('pi'), 35))
3.1415926535897932384626433832795029
The reason why this doesn't work is rounding. Specifically, the above result appears to indicate that the 35
-th significant digit of pi is nine, when actually it is an eight that was rounded up:
>> disp(vpa(sym('pi'), 36))
3.14159265358979323846264338327950288
From the above, it would appear that a solution is to ask for one extra decimal and throw it away, so that the last surviving decimal doesn't have rounding issues. But this does not work in general either, because rounding can cause carry. See this example in Matlab:
>> disp(vpa(sym('pi'), 79))
3.141592653589793238462643383279502884197169399375105820974944592307816406286209
>> disp(vpa(sym('pi'), 80))
3.141592653589793238462643383279502884197169399375105820974944592307816406286209
>> disp(vpa(sym('pi'), 81))
3.141592653589793238462643383279502884197169399375105820974944592307816406286209
>> disp(vpa(sym('pi'), 82))
3.141592653589793238462643383279502884197169399375105820974944592307816406286208999
>> disp(vpa(sym('pi'), 83))
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986
or in Octave:
>> disp(vpa(sym('pi'), 79))
3.141592653589793238462643383279502884197169399375105820974944592307816406286209
>> disp(vpa(sym('pi'), 80))
3.1415926535897932384626433832795028841971693993751058209749445923078164062862090
>> disp(vpa(sym('pi'), 81))
3.14159265358979323846264338327950288419716939937510582097494459230781640628620900
>> disp(vpa(sym('pi'), 82))
3.141592653589793238462643383279502884197169399375105820974944592307816406286208999
>> disp(vpa(sym('pi'), 83))
3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986
As can be seen,
- Increasing the number of required decimals from
79
to80
or81
invpa
gives the same answer in Matlab, because rounding and carry make the last digits zero and Matlab trims trailing zeros. - Octave doesn't trim, so it shows those zeros, but they are still incorrect.
Thus, both in Matlab and in Octave, correctly obtaining the first 79
significant digits requires that at least three extra digits be asked for in this case.
The above examples illustrate that
- The last digits of
vpa
may be off because of rounding; - It doesn't always suffice to ask for one extra digit;
- The number of extra digits required to avoid rounding issues can be arbitrarily large. This happens when there is a long run of nines right after the wanted digits.
So, is there a way to obtain the first W
significant digits of a number with guarantee that they are correct, i.e not affected by rounding issues?