4

For some reason 2^52 is equal to 2^52+1 in Matlab, but why ? And how can i fix this ? For more info please run the code below and check the results.

Here it is the outputs(with vpa):

>> format long
>> digits(500)
>> vpa(2^52)

ans =

4503599627370496.0

>> vpa(2^52+1)

ans =

4503599627370496.0

>> isequal(vpa(2^52), vpa(2^52+1))

ans =

     1

>> vpa(2^52+1)

ans =

4503599627370496.0

>> ans+1

ans =

4503599627370497.0

>> vpa(2^52+1000)

ans =

4503599627371496.0

https://ibb.co/iDDAwF

(the outputs without vpa)

>> 2^52

ans =

    4.503599627370496e+015

>> 2^52+1

ans =

    4.503599627370497e+015

>> isequal(2^52, 2^52+1)

ans =

     0

>> 2^52+1

ans =

    4.503599627370497e+015

>> ans+1

ans =

    4.503599627370498e+015

>> 2^52+1000

ans =

    4.503599627371496e+015

Edit: This isn't a duplicate and has nothing to do with floating point errors.

Kitiara
  • 343
  • 6
  • 21

1 Answers1

7
vpa_item=vpa('2^52');
vpa_item2=vpa('1+2^52');
disp(isequal(vpa_item, vpa_item2));

results in 0

You can use "symbolic expressions" to bypass limitations of finite or floating point arithmetic on the input end.

--edit--

The linked page says vpa(1+sym(2)^52) is the paradigmatic expression, although both methods should work.

What will not work (in general) is

value_affected_by_imprecise_arithemetic = 1+2^52;
vpa(value_affected_by_imprecise_arithemetic)
Mikhail
  • 7,749
  • 11
  • 62
  • 136
  • So do you know why I am getting the correct result doing this as the OP did and the OP is getting incorrect results? – RSon1234 Feb 22 '17 at 07:41
  • @RSon1234 So, in R2015a `isequal(vpa(2^52), vpa(2^52+1))` results in `0` which is the correct behavior. Maybe due to a version mismatch? idk... – Mikhail Feb 22 '17 at 07:42
  • @Mikhail I just tested `isequal(vpa(num2str(2^52)), vpa(num2str(2^52+1)))` and it worked, thanks. – Kitiara Feb 22 '17 at 08:33
  • @Mikhail Which begs the question why `isequal(vpa(num2str(2^57)), vpa('2^57'))` = `0` ? and `isequal(vpa(str2num(num2str(2^57))), vpa('2^57'))` = `1` ? That is absolutely weird. – Kitiara Feb 22 '17 at 09:02
  • 1
    Don't use strings with symbolic math – this is advised against at the top of the documentation for `vpa` – and this functionality won't even work in future versions of Matlab. Use `vpa(2)^52+1` or `2^vpa(52)+1`, etc. Expression like `vpa(2^52+1)` may not work as `2^52+1` may be evaluated first in floating point (behavior in older Matlab versions may differ). – horchler Feb 22 '17 at 17:14
  • @Mikhail then why vpa(2^52+1000) is working but not vpa(2^52+1) ? Anyone know the reason ? Btw i have R2011a. – Kitiara Feb 23 '17 at 09:21
  • @horchler same question goes for you too – Kitiara Feb 23 '17 at 09:21
  • @Kitiara One reason is that `vpa(some_value)` requires that `some_value` is correct on the input end. When you write a complicated express, it is evaluated before it is transformed into a `vpa ` object, which defeats the purpose. – Mikhail Feb 23 '17 at 19:38
  • @Mikhail But the same thing happens for 2^52+1000 case too. – Kitiara Feb 23 '17 at 21:29
  • You need to convert to a vpa type before you do the math. ie, vpa(2)^52 – Mikhail Feb 23 '17 at 23:46