Borrar filtros
Borrar filtros

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?

2 visualizaciones (últimos 30 días)
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 comentarios
meh hadi
meh hadi el 21 de Abr. de 2018
Editada: meh hadi el 21 de Abr. de 2018
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 el 21 de Abr. de 2018

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.

Iniciar sesión para comentar.

Respuesta aceptada

John D'Errico
John D'Errico el 21 de Abr. de 2018
Editada: John D'Errico el 21 de Abr. de 2018

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.

Más respuestas (1)

Ameer Hamza
Ameer Hamza el 21 de Abr. de 2018
Editada: Ameer Hamza el 21 de Abr. de 2018

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.

Categorías

Más información sobre Logical en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by