Никогда не предполагайте, что такое число, как vpa (sin (pi/4)), является точным до полной точности, поскольку MATLAB обычно вычисляет число внутри вызова vpa с использованием арифметики с плавающей запятой, поэтому только с точностью до 16 цифр ,
Однако похоже, что это правильно. Например, мы знаем, что
sin(pi/4) == sqrt(2)/2
Давайте проверим этот результат. Я буду использовать 100 цифр точности, сравнивая как vpa, так и свои собственные инструменты HPF.
>> vpa(sin(pi/4),100)
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864
>> vpa(sqrt(sym(2))/2,100)
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864
>> sqrt(hpf(2,100))/2
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864
>> sin(hpf('pi',100)/4)
ans =
0.7071067811865475244008443621048490392848359376884740365883398689953662392310535194251937671638207864
Итак, я думаю, анализатор признал вклад как нечто символическое набор инструментов можно вычислить более точно. Как я уже говорил, будьте осторожны. Что такое грех (pi/12)?
>> vpa(sin(pi/12),100)
ans =
0.25881904510252073947640383266843855381011962890625
>> vpa('sin(pi/12)',100)
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655
>> vpa(sin(sym('pi')/12),100)
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655
>> sin(hpf('pi',100)/12)
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655
См., Что в первом случае анализатор нас не спас. В других случаях я заставил MATLAB вычислить правильное значение. На самом деле, немного усилий даст нам значение для sin (pi/12), как sqrt (2) * (sqrt (3) - 1)/4.
>> DefaultNumberOfDigits 100
>> (sqrt(hpf(3)) - 1)*sqrt(hpf(2))/4
ans =
0.2588190451025207623488988376240483283490689013199305138140032073150569747488019969223679746942496655
Дело в том, что не доверяйте парсеру, чтобы спасти вас здесь.
Редактировать: Как комментарий к замечанию Амро, я с уважением заявляю, что MATLAB делает здесь что-то интересное. Посмотрите, что vpa может вернуть правильные первые 100 цифр pi, даже когда передано pi как число двойной точности. Поскольку pi (как двойной) неверно прошло примерно 16-ю десятичную цифру, происходит что-то подозрительное.
>> vpa(pi,100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
>> vpa('pi',100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
vpa('pi',100) - vpa(pi,100)
ans =
0.0
В качестве доказательства этого факта давайте посмотрим, что находит HPF. HPF фактически принимает значение IEEE 754, которое хранится в двойном, затем преобразует его в номер HPF.
>> hpf(pi,100)
ans =
3.141592653589793115997963468544185161590576171875
>> hpf('pi',100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
>> hpf('pi',100) - hpf(pi,100)
ans =
0.0000000000000001224646799147353177226065932275001058209749445923078164062862089986280348253421170679821480800000000
Итак, ясно, MATLAB способен распознавать пи как нечто большее, чем просто двойной точности значение оно будет передано в качестве.
Edit2:
В самом деле, немного игры говорит мне, что здесь происходит. VPA является сложным, а не парсером. Рассмотрим долю 7/13. Если мы построим его как двойное, то распечатаем значение с плавающей запятой, хранящееся в его полной славе, мы видим, что это не совсем точно. Это так, как ожидалось.
>> sprintf('%.100f',7/13)
ans =
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000
7/13 является повторяющимся десятичным значением. Вот правильные цифры:
>> vpa('7/13',100)
ans =
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385
Теперь предположим, что мы пытаемся создать тот же номер. Здесь я буду проходить 7/13 в асе дважды, но я сделаю ошибку в нижних десятичных цифрах
>> sprintf('%.100f',0.538461538461538461777777777)
ans =
0.5384615384615384359179302009579259902238845825195312500000000000000000000000000000000000000000000000
Здесь мы видим, что VPA ловит и исправляет ошибку, связанные с "Я сделал, что распознающий то, что я прошел, на самом деле тождественно то же значение, что и в 7/13.
>> vpa(0.538461538461538461777777777,100)
ans =
0.5384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615384615385
Конечно, если я передам значение как строку, тогда vpa ошибается.
>> vpa('0.538461538461538461777777777',100)
ans =
0.538461538461538461777777777
Это объясняет, почему VPA способен уловить и правильно вычислить VPA (грех (пи/4), 100), к полной точности спросил. sin (pi/4) вычисляется как double, но тогда vpa видит его как число, которое совпадает с версией sqrt (2)/2 с двойной точностью.
Будьте осторожны, конечно. Например, vpa недостаточно умен, чтобы поймать этот простой сдвиг pi.
>> vpa(pi + 1,100)
ans =
4.141592653589793115997963468544185161590576171875
>> vpa(pi,100)
ans =
3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068
Вам может быть интересно прочитать этот вопрос: [В MATLAB, переменные ДЕЙСТВИТЕЛЬНО двойной точности по умолчанию?] (Http://stackoverflow.com/q/4227145/97160) – Amro