I want to do this:2.389​8769657358​3658648235​686+5.6387​6498376982​3768764987​9932 and i need all digits,vpa dosen't work properly.Is there any function to do it?

1 次查看(过去 30 天)
for a certain calculation I need at least 40 digits precision.I used vpa but look:
vpa(0.123456789123456789123456789) ans = 0.12345678912345678379658409085096 it changes the value of number I entered, which leads to incorrect results.is there any way to this.I want to do 2.38987696573583658648235686+5.6387649837698237687649879932.how can I do it?
  2 个评论
meh hadi
meh hadi 2018-4-21
编辑:meh hadi 2018-4-21
Thanks.it worker but I want put the result in another variable and again use that variable.is there any function that can do this: a=function(2.45); a= '2.45' ?
Ameer Hamza
Ameer Hamza 2018-4-21

One way is to define the starting number yourself. Once you get the result, you can convert the answer to char array using

char(vpa(first_number) + vpa(second_number))

Subsequently, you can easily use vpa() and char() to convert between two formats.

请先登录,再进行评论。

采纳的回答

John D'Errico
John D'Errico 2018-4-21
编辑:John D'Errico 2018-4-21

First, when you do this:

vpa(0.123456789123456789123456789)

MATLAB stores the input to VPA as a DOUBLE. MATLAB does all computations using doubles, stores all numbers by default as doubles. The symbolic toolbox is different. But MATLAB itself works on doubles.

So as far as MATLAB is concerned,

0.123456789123456789123456789

is just a number, a double precision number. And doubles are stored in a binary form, with 52 bits of precision in the mantissa. So, while you gave MATLAB a number with lots of decimal digits, only about the first 16 of them will be stored correctly. The rest have now been lost, thrown into the bit bucket.

sprintf('%0.55f',0.123456789123456789123456789)
ans =
  '0.1234567891234567837965840908509562723338603973388671875'

VPA is just a function. MATLAB does not know what you will do with any number. It stores it temporarily in a double, then passes the results to the function being called, in this case, VPA.

Of course, VPA takes the number, and sees a DOUBLE. All it sees is what it was passed. It sees that binary representation, and converts those binary bits into a number. So, this is actually what VPA sees:

sprintf('%0.55f',0.123456789123456789123456789)
ans =
  '0.1234567891234567837965840908509562723338603973388671875'

So, if I ask for at least 55 digits for VPA, I'll get the complete number stored.

vpa(0.123456789123456789123456789,55)
ans =
0.1234567891234567837965840908509562723338603973388671875

By the way, you get those extra digits because binary fractions essentially gain an extra digit each time you divide by 2. So the first few powers of 1/2 are:

1 ./ 2.^(0:10)'
ans =
                       1
                     0.5
                    0.25
                   0.125
                  0.0625
                 0.03125
                0.015625
               0.0078125
              0.00390625
             0.001953125
            0.0009765625

Remember, the mantissa of a double has 52 binary bits in it. While some binary fractions can be stored exactly, like 1/2 and 1/4, most decimals are not stored exactly as decimals.

Now, VPA is SOMETIMES a bit smarter than you might think. It can recognize some numbers even when they have been converted to approximate doubles.

x = 1/3
x =
        0.333333333333333
sprintf('%0.55f',x)
ans =
    '0.3333333333333333148296162562473909929394721984863281250'
vpa(x,55)
ans =
0.3333333333333333333333333333333333333333333333333333333

But, for the most part, VPA is pretty dumb. It takes what it has been passed. And MATLAB is not smarter than that, because it works in terms of doubles by default.

Ok, so you CANNOT pass in a number as a double in general to VPA, and expect it to get things right. But you can pass in the number as a string.

digits 40
vpa('0.123456789123456789123456789')
ans =
0.123456789123456789123456789

Once MATLAB understands that you entered that number into symbolic form, it has no problem. It stores it in high precision form.

digits 40
x = vpa('2.38987696573583658648235686');
y = vpa('5.6387649837698237687649879932');
x + y
ans =
8.0286419495056603552473448532

Once x and y are symbolic numbers, they will stay as such.

exp(x)*y^2
ans =
346.9591673851377328054605380636824962144

So you are now working in 40 digits of precision. Computations will be a lot slower of course, but you cannot expect everything.

I would note that you could have done exactly the same thing using my HPF toolbox, found on the file exchange, but the symbolic toolbox is entirely sufficient here.

更多回答(1 个)

Ameer Hamza
Ameer Hamza 2018-4-21
编辑:Ameer Hamza 2018-4-21

You can first convert these numbers to char array or string and then apply vpa as follow

digits(40)
first_number = '2.38987696573583658648235686';
second_number = '5.6387649837698237687649879932';
result = vpa(first_number) + vpa(second_number)

This way you will not lose precision.

类别

Help CenterFile Exchange 中查找有关 Numbers and Precision 的更多信息

Community Treasure Hunt

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

Start Hunting!

Translated by