目录
数值类型
整数和浮点数据。MATLAB® 中的数值类包括有符号和无符号整数、单精度和双精度浮点数。默认情况下,MATLAB 以双精度浮点形式存储所有数值。(不能更改默认类型和精度。)可以选择以整数或单精度形式存储任何数值或数值数组。与双精度数组相比,以整数和单精度数组形式存储数据更节省内存。所有数值类型都支持基本的数组运算,例如添加索引、重构和数学运算。
函数
创建数值变量
double | 双精度数组 |
signle | 单精度数组 |
int8 | 8 位有符号整数数组 |
int16 | 16 位有符号整数数组 |
int32 | 32 位有符号整数数组 |
int64 | 64 位有符号整数数组 |
uint8 | 8 位无符号整数数组 |
uint16 | 16 位无符号整数数组 |
uint32 | 32 位无符号整数数组 |
uint64 | 64 位无符号整数数组 |
在数值类型之间转换
cast | 将变量转换为不同的数据类型 |
typecast | 在不更改基础数据的情况下转换数据类型 |
查询类型和值
isinteger | 确定输入是否为整数数组 |
isfloat | 确定输入是否为浮点数组 |
isnumeric | 确定输入是否为数值数组 |
isreal | 确定数组是否为实数数组 |
isfinite | 确定哪些数组元素为有限 |
isinf | 确定哪些数组元素为无限值 |
isnan | 确定哪些数组元素为 NaN |
数值范围
eps | 浮点相对精度 |
flintmax | 浮点格式的最大连续整数 |
Inf | 创建所有值均为Inf的数组 |
intmax | 特定整数类型的最大值 |
intmin | 指定整数类型的最小值 |
NaN | 创建所有值均为 NaN 的数组 |
realmax | 最大的正浮点数 |
realmin | 最小标准浮点数 |
主题
浮点数
MATLAB® 以双精度或单精度格式表示浮点数。默认为双精度,但可以通过一个简单的转换函数将任何数值转换为单精度数值。
双精度浮点
MATLAB 根据适用于双精度的 IEEE® 754 标准来构造双精度(即 double)数据类型。以double形式存储的任何值都需要64位,并按照下表所示进行格式化:
位 | 用法 |
---|---|
63 | 符号(0 = 正号、1 = 负号) |
62 到 52 | 指数,偏差为 1023 |
51 到 0 | 数值 1.f 的小数 f |
单精度浮点
MATLAB 根据适用于单精度的 IEEE 754 标准来构造单精度(即 single)数据类型。以 single 形式存储的任何值都需要 32 位,并按照下表所示进行格式化:
位 | 用法 |
---|---|
31 | 符号(0 = 正号、1 = 负号) |
30 到 23 | 指数,偏差为 127 |
22 到 0 | 数值 1.f 的小数 f |
由于 MATLAB 使用 32 位来存储 single 类型的数值,因此与使用 64 位的double类型的数值相比,前者需要的内存更少。但是,由于它们是使用较少的位存储的,因此 single 类型的数值所呈现的精度要低于 double 类型的数值。
创建浮点数据
一般使用双精度来存储大于 3.4 x 1038 或约小于 -3.4 x 1038 的值。对于位于这两个范围之间的数值,可以使用双精度,也可以使用单精度,但单精度需要的内存更少。
创建双精度数据
由于MATLAB的默认数值类型为 double,因此可以通过一个简单的赋值语句来创建 double 值:
x = 25.783;
whos函数显示,MATLAB 已为您刚在x中存储的值创建了一个double类型的 1x1 数组:
whos x
Name Size Bytes Class
x 1x1 8 double
如果只想验证x是否为浮点数,请使用isfloat。如果输入为浮点数,此函数将返回逻辑值 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 的属性。此结构体的 bytes 字段显示,当以 single 形式存储 x 时,该变量仅需要 4 字节,而以double形式存储则需要8字节:
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
最大和最小单精度值
在用参数 'single' 调用
MATLAB 函数realmax和realmin时,这两个函数会分别返回可以用 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)。由于单精度数的数量少于双精度数的数量,因此单精度数之间的间隔也大于双精度数之间的间隔。这意味着,单精度算术运算的结果精度要低于双精度算术运算的结果精度。
对于类型为 double 的双精度数 x,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 或 FORTRAN 编写的应用程序以及 MATLAB。