Ответ 1
Они - двойники. Vpa() просто выбирает отображение незначительных цифр за пределами относительной точности с плавающей точкой, где printf() и disp() усекаются или обнуляются.
Вы получаете только свои исходные четыре цифры, потому что буквальный, который вы выбрали для инициализации num, просто является точным десятичным расширением двоичного двойного значения, поскольку он был скопирован и вставлен с вывода расширения фактическое двойное значение от другого вопроса. Он не будет работать для других близлежащих значений, как показано в добавлении к вашему "БОНУСУ".
Точнее, все числовые литералы в Matlab производят значения типа double. Они преобразуются в двоичное двойное значение, которое ближе всего к десятичному значению, которое они представляют. По сути, цифры в литеральном представлении за пределами точности двойного типа молча отбрасываются. Когда вы копируете и вставляете вывод vpa для создания новой переменной, как это сделал другой вопрос с инструкцией "e =...", вы инициализируете значение из литерала вместо прямого обращения с результатом предыдущее выражение.
Различия здесь только в форматировании вывода. Я думаю, что происходит то, что vpa() берет двойной двойной двоичный двойник и рассматривает его как точное значение. Для данного значения двоичной мантиссы-экспоненты вы можете рассчитать десятичный эквивалент произвольно большого количества десятичных знаков. Если у вас ограниченная точность ( "ширина" ) в двоичном значении, как и у любого типа данных фиксированного размера, значительная часть этих десятичных цифр значительна. Параметры Sprintf() и Matlab по умолчанию обрабатывают это путем усечения вывода или отображения незначительных цифр как 0. Vpa() игнорирует пределы точности и продолжает вычислять столько знаков после запятой, сколько вы запрашиваете.
Эти дополнительные цифры являются фиктивными, в том смысле, что если бы они были заменены другими значениями для создания близкого десятичного значения, все они бы округлились до того же двоичного двойного значения.
Вот способ показать это. Эти значения x одинаковы при сохранении в двойниках, и все они будут представлены одинаковыми с помощью vpa().
x = [
2.7182818284590455348848081484902650117874145507812500
2.7182818284590455348848081484902650117874145507819999
2.7182818284590455348848
2.71828182845904553488485555555555555555555555555555
exp(1)
]
unique(x)
Вот еще один способ продемонстрировать это. Вот два двойника, которые очень близки друг к другу.
x0 = exp(1)
x1 = x0 + eps(x0)
Vpa (x0) и vpa (x1) должны давать выходы, которые сильно отличаются от 16-й цифры. Однако вы не должны создавать двойное значение x, так что vpa (x) создает десятичное представление, которое находится между vpa (x0) и vpa (x1).
(ОБНОВЛЕНИЕ: Амро указывает, что вы можете использовать fprintf('%bx\n', x)
для отображения точного представления базового двоичного значения в шестнадцатеричном формате. Вы можете использовать это, чтобы подтвердить, что карта букв в том же двойном.)
Я подозреваю, что vpa() ведет себя так, потому что обрабатывает свои входы как точные значения и полиморфно поддерживает другие типы Matlab из Symbolic Toolbox, которые имеют более высокую точность, чем двойные. Эти значения должны быть инициализированы с помощью других средств, кроме числовых литералов, поэтому sym() принимает строку как входную и "vpa (exp (1))" отличается от "vpa (sym ('exp (1)" ) )".
Имеют смысл? Извините за долговечность.
(Примечание. У меня нет Symbolic Toolbox, поэтому я не могу сам тестировать vpa().)