vpa Does Not Show the Required Number of Significant Digits

3 views (last 30 days)
For the below example, MATLAB shows exactly 50 significant digits:
>> vpa(cos(10),50)
ans =
-0.83907152907645243811174395887064747512340545654297
But here it shows a much fewer digits than requested.
>> vpa(cos(10),100)
ans =
-0.83907152907645243811174395887064747512340545654296875
Why? If I embed 10 with sym, it works fine:
>> vpa(cos(sym(10)),100)
ans =
-0.8390715290764524522588639478240648345199301651331685468359537310487925868662707684009337127604221389
Why can't MATLAB produce the desired output without sym? For example, when vpa applies to pi, then no need for sym:
>> vpa(pi,100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068

Answers (2)

the cyclist
the cyclist on 11 Sep 2021
I'd have to spend more time to figure out the truly complete answer to this, but I'm confident that the reason is that the MATLAB representation of cos(10) is zero after the 53rd digit. So, the trailing zeros are dropped, similarly to the reason why
vpa(6.457000,10)
ans = 
6.457
doesn't show all of the trailing zeros.
This kinda just shifts to the question, "Why is the MATLAB representation of cos(10) zero after 53 digits?". I don't have a full answer to that off the top of my head. I am sure someone else here will. :-)
  2 Comments
Kareem Elgindy
Kareem Elgindy on 11 Sep 2021
Edited: Kareem Elgindy on 11 Sep 2021
You have a point indeed in your nice explanation and examples. But, when you said the MATLAB representation of cos(10) is zero after the 53rd digit, aren't we missing an important fact here, which is cos(10) is a double-precision floating point number, and by default, MATLAB uses 16 digits of precision, so it is already understood that the trailing digits after 16 digits are zeros.
the cyclist
the cyclist on 11 Sep 2021
While it is true that cos(10) is accurate to 16 digits when stored as double-precision, it does not follow that the remaining (potentially spurious) digits are zeros. You can see this with
sprintf('%43.40f',cos(10))
ans = '-0.8390715290764524381117439588706474751234'
If you compare this to, for example, the Wolfram Alpha output, you will see they diverge after 16 places. But the digits aren't zero.

Sign in to comment.


Walter Roberson
Walter Roberson on 11 Sep 2021
No, it is not correct that trailing digits after 16 digits are zero. Double precision is binary and cannot exactly represent fractions of 10 (except for special ones like 5/10 or 25/100)
fprintf('%.999g\n', cos(10))
When the Symbolic toolbox is asked to convert a double precision number, it goes through the following algorithm:
  • is the number close to being a rational multiple of π with denominator no more than 10000 ? If so, the emit the rational fraction time symbolic π
  • use a continued-fraction algorithm to determine whether the number is close to being a rational number times the square root of an integer
  • use a continued-fraction algorithm to determine whether the number is close to being a rational number
  • if none of the above, use the exact binary ratio
So vpa(pi,100) works because the floating point constant returned by pi is recognized as being a multiple of π first, and then vpa() of π can produce an indefinite number of digits of π
vpa(cos(10), 100) calculates cos(10) in double precision, and that gets processed though the algorithm, which gives up and represents it as an exact binary ratio -7557684451371807/9007199254740992 -- which happens to be representable in decimal in fewer than 100 digits.

Tags

Products


Release

R2021a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!