MATLAB® представляет числа с плавающей запятой или в с двойной точностью или в формат с одинарной точностью. Значение по умолчанию удваивает точность, но можно сделать любую одинарную точность номера с простой функцией преобразования.
MATLAB создает с двойной точностью (или double
) тип данных согласно IEEE® Standard 754 для двойной точности. Любое значение, сохраненное как double
, требует 64 битов, отформатированных как показано в приведенной ниже таблице:
Биты |
Использование |
---|---|
|
Знак ( |
|
Экспонента, смещенная |
|
Фракционируйте |
MATLAB создает с одинарной точностью (или single
) тип данных согласно Стандарту IEEE 754 для одинарной точности. Любое значение, сохраненное как 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
является числом с плавающей запятой. Эта функция возвращает логическую единицу (true
), если входной параметр является числом с плавающей запятой и логическим нолем (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
в структуре. Поле 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
'double'
int*
или uint*
— Результат имеет совпадающий тип данных как целочисленный операнд
'char'
логический
Этот пример выполняет арифметику на данных типов char
и double
. Результат имеет тип double
:
c = 'uppercase' - 32; class(c) ans = double char(c) ans = UPPERCASE
Можно выполнить основные арифметические операции с single
и любым из следующих других классов. Результатом всегда является single
:
единственный
'double'
'char'
логический
В этом примере, 7,5 значений по умолчанию, чтобы ввести double
и результат имеет тип single
:
x = single([1.32 3.47 5.28]) .* 7.5; class(x) ans = single
Для double
и классов single
, существует самый большой и самый маленький номер, который можно представлять с тем типом.
realmax
функций MATLAB и 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
realmax
функций MATLAB и 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 выполняются в с двойной точностью арифметике, соответствующей стандарту IEEE 754. Поскольку компьютеры только представляют числа конечной точности (двойная точность призывает к 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
, могут использоваться, чтобы компенсировать эффекты катастрофической отмены.
Округление, отмена и другие черты арифметического объединения с плавающей точкой, чтобы произвести потрясающие вычисления при решении проблем линейной алгебры. 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] Moler, Клив. “Плавающие точки”. Новости MATLAB и примечания. Упадите, 1996.
[2] Moler, Клив. Числовое вычисление с MATLAB. Натик, MA: MathWorks, Inc., 2004.