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.