MATLAB® представляет числам с плавающей запятой с двойной точностью или форматом с одинарной точностью. По умолчанию это двойная точность, но вы можете сделать любое число одинарной точности с простой функцией преобразования.
MATLAB создает двойную точность (или double) тип данных согласно IEEE® Стандарт 754 для двойной точности. Любое значение, сохраненное как double требуется 64 бита, форматированных как показано в таблице ниже:
|
Биты |
Использование |
|---|---|
|
|
Знак ( |
|
|
Экспонента, смещенная |
|
|
Дробные |
MATLAB создает одинарную точность (или single) тип данных согласно стандарту 754 IEEE для одинарной точности. Любое значение, сохраненное как single требуется 32 бита, форматированных как показано в таблице ниже:
|
Биты |
Использование |
|---|---|
|
|
Знак ( |
|
|
Экспонента, смещенная |
|
|
Дробные |
Поскольку MATLAB хранит номера типов single используя 32 бита, они требуют меньше памяти, чем числа типов double, которые используют 64 бита. Однако, поскольку они хранятся с меньшим количеством бит, номера типов single представлены с меньшей точностью, чем числа типов double.
Используйте двойную точность для хранения значений, превышающих приблизительно 3,4 x 1038 или менее чем приблизительно -3,4 x 1038. Для чисел, которые находятся между этими двумя пределами, можно использовать или двойную- или одинарную точность, но одинарная точность требует меньшей памяти.
Потому что числовой тип по умолчанию для MATLAB double, можно создать double с простым оператором присваивания:
x = 25.783;
whos функция показывает, что MATLAB создал массив типа 1 на 1 double для значения, которое вы только что хранили в x:
whos x Name Size Bytes Class x 1x1 8 double
Использовать isfloat если вы просто хотите проверить это x является число с плавающей запятой. Эта функция возвращает логический 1 (true) если вход является числом с плавающей запятой и логическим 0 (false) в противном случае:
isfloat(x) ans = logical 1
Можно преобразовать другие числовые данные, символы или строки и логические данные в двойную точность с помощью функции MATLAB, double. Этот пример преобразует целое число со знаком в плавающую точку двойной точности:
y = int64(-589324077574); % Create a 64-bit integer x = double(y) % Convert to double x = -5.8932e+11
Потому что MATLAB хранит числовые данные как double по умолчанию вам нужно использовать single функция преобразования для создания числа с одной точностью:
x = single(25.783);
whos функция возвращает атрибуты переменной x в структуре. The bytes поле этой структуры показывает, что когда x хранится как сингл, это требует всего 4 байта по сравнению с 8 байтами для хранения в виде double:
xAttrib = whos('x');
xAttrib.bytes
ans =
4
Можно преобразовать другие числовые данные, символы или строки и логические данные в одну точность, используя single функция. Этот пример преобразует целое число со знаком в плавающую точку с одной точностью:
y = int64(-589324077574); % Create a 64-bit integer x = single(y) % Convert to single x = single -5.8932e+11
В этом разделе описываются классы, которые можно использовать в арифметических операциях с числами с плавающей запятой.
Можно выполнить основные арифметические операции с double и любой из следующих других классов. Когда один или несколько операндов являются целым числом (скаляром или массивом), double операнд должен быть скаляром. Результатом является тип double, за исключением тех случаев, когда указано иное:
single - Результатом является тип single
double
int* или uint* - Результат имеет тот совпадающий тип данных, что и целочисленный операнд
char
logical
Этот пример выполняет арифметику данных типов char и double. Результатом является тип double:
c = 'uppercase' - 32; class(c) ans = double char(c) ans = UPPERCASE
Можно выполнить основные арифметические операции с single и любой из следующих других классов. Результат всегда single:
single
double
char
logical
В этом примере 7.5 по умолчанию задает тип double, и результат имеет тип single:
x = single([1.32 3.47 5.28]) .* 7.5; class(x) ans = single
Для double и single классы, существует самое большое и самое маленькое число, которое можно представлять с этим типом.
Функции MATLAB realmax и realmin возвращает максимальное и минимальное значения, которые можно представлять с помощью double тип данных:
str = 'The range for double is:\n\t%g to %g and\n\t %g to %g';
sprintf(str, -realmax, -realmin, realmin, realmax)
ans =
The range for double is:
-1.79769e+308 to -2.22507e-308 and
2.22507e-308 to 1.79769e+308
Числа больше realmax или меньше -realmax присвоены значения положительной и отрицательной бесконечности, соответственно:
realmax + .0001e+308 ans = Inf -realmax - .0001e+308 ans = -Inf
Функции MATLAB realmax и realmin, при вызове с аргументом 'single', верните максимальное и минимальное значения, которые вы можете представлять с single тип данных:
str = 'The range for single is:\n\t%g to %g and\n\t %g to %g';
sprintf(str, -realmax('single'), -realmin('single'), ...
realmin('single'), realmax('single'))
ans =
The range for single is:
-3.40282e+38 to -1.17549e-38 and
1.17549e-38 to 3.40282e+38Числа больше realmax('single') или меньше -realmax('single') присвоены значения положительной и отрицательной бесконечности, соответственно:
realmax('single') + .0001e+038
ans =
single
Inf
-realmax('single') - .0001e+038
ans =
single
-InfЕсли результат арифметических расчетов с плавающей точностью не так точен, как вы ожидали, это, вероятно, вызвано ограничениями оборудования вашего компьютера. Вероятно, ваш результат был немного менее точным, потому что оборудование имело недостаточно биты, чтобы представлять результат с идеальной точностью; поэтому это усекло получившееся значение.
Поскольку существует только конечное число чисел двойной точности, вы не можете представлять все числа в хранилище двойной точности. На любом компьютере существует небольшая погрешность между каждым числом двойной точности и следующим большим числом двойной точности. Вы можете определить размер этой погрешности, которая ограничивает точность ваших результатов, используя eps функция. Например, чтобы найти расстояние между 5 и следующее большее число двойной точности, введите
format long
eps(5)
ans =
8.881784197001252e-16Это говорит вам, что нет чисел двойной точности между 5 и 5 + eps(5). Если расчет двойной точности возвращает ответ 5, результат точен только в eps(5).
Значение eps(x) зависит от x. Этот пример показывает, что, как x становится больше, как и eps(x):
eps(50)
ans =
7.105427357601002e-15Если вы вводите eps не имея входного параметра, MATLAB возвращает значение eps(1), расстояние от 1 к следующему большему числу двойной точности.
Точно так же существуют погрешности между любыми двумя числами с одной точностью. Если x имеет тип single, eps(x) возвращает расстояние между x и следующее большее число с одной точностью. Для примера,
x = single(5); eps(x)
возвраты
ans = single 4.7684e-07
Обратите внимание, что этот результат больше eps(5). Поскольку чисел с одной точностью меньше, чем чисел с двойной точностью, погрешности между числами с одной точностью больше, чем погрешности между числами с двойной точностью. Это означает, что результаты арифметики с одной точностью менее точны, чем в арифметике с двойной точностью.
Для числового x типа double, eps(single(x)) задает верхнюю границу для суммы, которая x округлено, когда вы преобразовываете его из double на single. Для примера при преобразовании числа двойной точности 3.14 на single, он округлен
double(single(3.14) - 3.14) ans = 1.0490e-07
Сумма, которая 3.14 скруглено меньше, чем
eps(single(3.14)) ans = single 2.3842e-07
Почти все операции в MATLAB выполняются в арифметике двойной точности, соответствующей стандарту 754 IEEE. Поскольку компьютеры представляют числа только с конечной точностью (двойная точность вызывает 52 бита мантиссы), расчеты иногда дают математически неинтуитивные результаты. Важно отметить, что эти результаты не являются ошибками в MATLAB.
Используйте следующие примеры, чтобы помочь вам идентифицировать эти случаи:
Десятичное число 4/3 не является точно представимой как двоичная дробь. По этой причине следующее вычисление не дает нуля, а скорее показывает количество eps.
e = 1 - 3*(4/3 - 1) e = 2.2204e-16
Точно так же 0.1 не является точно представимым в виде двоичного числа. Таким образом, вы получаете следующее неинтуитивное поведение:
a = 0.0; for i = 1:10 a = a + 0.1; end a == 1 ans = logical 0
Обратите внимание, что порядок операций может иметь значение в расчете:
b = 1e-16 + 1 - 1e-16; c = 1e-16 - 1e-16 + 1; b == c ans = logical 0
Существуют погрешности между числами с плавающей запятой. Как числа становятся больше, так и погрешности, о чем свидетельствует:
(2^53 + 1) - 2^53
ans =
0Начиная с pi это на самом деле не, не удивительно, что sin(pi) не точно равен нулю:
sin(pi)
ans =
1.224646799147353e-16Когда вычитания выполняются с почти равными операндами, иногда отмена может произойти неожиданно. Ниже приведён пример гашения, вызванного болотистым течением (потеря точности, делающая сложение незначительным).
sqrt(1e-16 + 1) - 1
ans =
0Некоторые функции в MATLAB, такие как expm1 и log1p, может использоваться для компенсации эффектов катастрофической отмены.
Округление, cancellation и другие признаки арифметики с плавающей точкой объединяются, чтобы получить поразительные расчеты при решении задач линейной алгебры. MATLAB предупреждает, что следующая матрица A является плохо обусловленной, и поэтому система Ax = b может быть чувствительным к небольшим возмущениям:
A = diag([2 eps]);
b = [2; eps];
y = A\b;
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 1.110223e-16.Это лишь несколько примеров, показывающих, как арифметика с плавающей точкой IEEE влияет на расчеты в MATLAB. Обратите внимание, что затронуты все расчеты, выполненные в арифметике IEEE 754, сюда входят приложения, написанные на C или ФОРТРАН, а также MATLAB.
[1] Молер, Клеве. «Плавающие точки». Новости и заметки MATLAB. Осень, 1996.
[2] Молер, Клеве. Числовые вычисления с MATLAB. Natick, MA: The MathWorks, Inc., 2004.