vpa Does Not Show the Required Number of Significant Digits

19 ビュー (過去 30 日間)
Kareem Elgindy
Kareem Elgindy 2021 年 9 月 11 日
回答済み: Walter Roberson 2021 年 9 月 11 日
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

回答 (2 件)

the cyclist
the cyclist 2021 年 9 月 11 日
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 件のコメント
the cyclist
the cyclist 2021 年 9 月 11 日
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.

サインインしてコメントする。


Walter Roberson
Walter Roberson 2021 年 9 月 11 日
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.

タグ

製品


リリース

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by