Це питання виникло з чогось дивного, що я помітив після подальшого розслідування цього питання ...
Я завжди розумів, що змінні MATLAB за замовчуванням мають подвійну точність . Отже, якби я зробив щось на зразок оголошення змінної з 20 цифрами після десяткової коми:
>> num = 2.71828182845904553488;
>> class(num) % Display the variable type
ans =
double
Я би очікував, що останні 4 цифри будуть проігноровані, оскільки відносна точність з плаваючою комою становить близько 10-16 :
>> eps(num)
ans =
4.440892098500626e-016
Якщо я спробую відобразити число з більш ніж 16 цифр після десяткової коми (використовуючи або fprintf
або sprintf
), я отримую те, що я очікую побачити:
>> fprintf('%0.20f\n', num)
2.71828182845904550000
>> sprintf('%0.20f', num)
ans =
2.71828182845904550000
Іншими словами, цифри з 17 по 20 дорівнюють 0.
Але все стає дивно, коли я переходжу num
до арифметичної функції змінної точності в Наборі символьних інструментів , кажучи їй, щоб вона представляла число, використовуючи 21 цифру точності:
>> vpa(num, 21)
ans =
2.71828182845904553488
ЩО?! Ці останні 4 цифри знову з’явилися! Чи їх не слід було втратити, коли початковий номер, який я ввів, зберігався як змінна подвійної точності num
? Оскільки num
це змінна з подвійною точністю, коли вона передається vpa
, як vpa
дізнатися, що це таке?
Моє найкраще здогадування щодо того, що відбувається, це те, що MATLAB внутрішньо представляє num
з більшою точністю, ніж подвійне, оскільки я ініціалізував його числом із більшою кількістю цифр після десяткової коми, ніж змінна подвійної точності могла б обробити. Це справді те, що відбувається, або щось інше відбувається?
БОНУС: І ось додаткове джерело плутанини, якщо у вас ще немає мігрені з вищезазначеного ...
>> num = 2.71828182845904553488; % Declare with 20 digits past the decimal
>> num = 2.718281828459045531; % Re-declare with 18 digits past the decimal
>> vpa(num, 21)
ans =
2.71828182845904553488 % It's the original 20-digit number!!!