专业编程基础技术教程

网站首页 > 基础教程 正文

轻松掌握MATLAB - 3.1 MATLAB的基本数据类型(2)

ccvgpt 2025-03-12 12:34:49 基础教程 2 ℃

上一篇:轻松掌握MATLAB - 3.1 MATLAB的基本数据类型(1)


3. 数值型

MATLAB以数值计算著称,数值型数据是程序中最重要的数据。MATLAB共定义了10种数值类型,包括2种浮点型和8种整数型。在MATLAB中,默认的数值类型是double,即双精度浮点型,并且默认数值类型是不可更改的。也就是说,我们无法将其他数值类型设置为MATLAB的默认数值类型。除了double类型外,其余数值类型都需要通过相应的函数来显式的创建,这实质上是通过对默认的double类型进行类型来实现的。

(1)浮点型

浮点型数据包括单精度浮点型(single)和双精度浮点型(double)。二者的主要区别在于所致内存大小、取值范围和精度:

轻松掌握MATLAB - 3.1 MATLAB的基本数据类型(2)

  • 内存占用:single型数据占用4个字节,而double型数据占用 8个字节;
  • 取值范围:double型能表达的数值范围要比single型大得多;
  • 精度:由于计算机采用二进制来表示数值,这使得它无法精确表达所有的浮点数。计算机能表达的两个浮点数之间的最小距离,称为浮点数的相对误差。在MATLAB中,这个误差可由eps函数得到。由于介于计算机可表达的两个相邻的浮点数之间的数计算机无法区分,因此认为它们是相等的。double型的eps要远小于single型的,因此double型能表达的精度更高。

示例如下:

第一行代码创建了一个double型变量db,因double型是MATLAB的默认数值类型,因此无需专门声明。第二行代码通过single函数,将db转换为了single型并赋值给sg。从whos函数返回信息中的Bytes列可以看出,double型占8个字节,而single型仅占4个字节。

用realmax和realmin函数可分别返回 IEEE标准定义的单精度或双精度浮点数的最大和最小(正)值。例如,

%floatRange.m
floatType = 'single';
fprintf('%s can express positive float numbers in [%e, %e]. \n', ...
      floatType, realmin(floatType), realmax(floatType));

single can express positive float numbers in [1.175494e-38, 3.402823e+38].

从执行结果可以看出,single型可表达的数值范围是 [1.175494e-38, 3.402823e+38]。 将上述代码中的floatType设为 'double',重新执行可以得到双精度正浮点数的范围为 [2.225074e-308, 1.797693e+308]。显然,double型可表达的数值范围比single型可表达的数值范围的大得多。

在计算机中,浮点数是以二进制表示的。一个计算机可表达的浮点数与下一个可表达的浮点数之间的距离等于,其中n是一个整数,其大小与当前浮点数的大小和计算机软硬件配置有关。用eps函数可以得到当前数值与下一个浮点数值之间的距离。例如:1与下一个浮点数之间的距离为:

可以看出,两个相邻double型数值之间的距离要比两个相邻的single型数值之间的距离小得多,即double型具有更高的精度。由于距离小于eps的两个数值计算机无法表达,所以会认为它们是相等的。例如,

同理,比realmax大的下一个数应该是无穷大:

返回结果中的Inf是MATLAB预定义的特殊常数之一,代表数学上的无穷大。此外,Inf本身也是一个内置函数,可以用来创建全Inf的数组。有关Inf的详细信息请doc Inf查询。

isfloat函数可以判断其输入是否为浮点数,而isfinite或isinf函数可以判断其输入是否为无穷大。例如,


【说明】

  • 三个特殊的浮点数:无穷大Inf(如1/0)、非数NaN(如0/0)和空[];
  • 由于计算机使用有限精度的浮点数来表示数值,因此在计算过程中,浮点数误差有时可能会导致数学上的非预期结果。例如,sin(pi)并不严格等于0。因此,程序中应尽量避免通过比较两个浮点数是否相等来作为条件。
  • 深入了解MATLAB中的浮点数请doc Floating-Point Numbers。

(2)整数型

MATLAB提供了8种整数类型,其中包括4种有符号整型(int8, int16, int32, int64)和4种无符号整型(uint8, uint16, uint32, uint64)。这些整数类型之间的主要区别在于:

  • 内存占用:整型名称中int后面的数字表示的是该类型数据在内存中所占的位(bit)数,而8位为一个字节(byte)。
  • 数值范围:n-bit有符号整型能表达的整数范围为,而n-bit无符号整型的范围为

每种整型数据可以表达的最大值和最小值可以通过intmax和intmin函数来查询。示例如下:

%intRange.m
intType = 'int8';
fprintf('%s can express integers in [%d, %d]. \n',...
      intType, intmin(intType), intmax(intType));

int8 can express integers in [-128, 127].

将上面代码中的intType赋值为其他整型名称,即可查询相应整数类型可表达的数值范围。整型实际上也是对默认的double类型作类型转换得到的,整型的名称即为该类型的转换函数。例如:

可以看出,在转换为整型的过程中,非整数会被四舍五入;如果数值超过了整型所能表达的数值范围(发生溢出),则会被截断为该整型可表达的最近的整数,而且不会报错!!!

用isinteger函数可以检验其输入变量是否为整型。例如:

用通用的isa函数可以做更具体的类型判断。该函数的基本语法如下:

tf = isa(A,dataType)

判断变量A的数据类型是否为dataType指定的类型。datatype可以是任意数据类型或类别名称,也可以是MATLAB类的名称。例如,



【说明】

  • 在命令行输入isa(a,后按Tab键,提示框中会列出所有可选查询项目。
  • 新版MATLAB中,当在 Editor 或 Live Editor 中输入代码时,会自动弹出提示。可以通过 Preferences 对话框中 Editor/Debugger-Automatic Completions-Show suggestions automatically 复选框来开启或关闭此功能。

(3)二进制和十六进制数

MATLAB中默认的整数为十进制数。然而,在一些特殊情况下(例如操作单片机的寄存器),二进制和十六进制更符合数据的使用习惯。因此,MATLAB也支持二进制和十六进制,并提供了多个函数来实现不同进制数之间的转换。

在MATLAB中,二进制和十六进制数有两种表示方式:

  • 字符方式:用字符向量来表示和存储二进制和十六进制数。例如,十六进制数'2A'表示十进制的42。MATLAB内置的进制转换函数返回的都是字符格式。
  • 字面值方式:这是自R2019b版本开始才引入的表示方式。十六进制以0x或0X作为前缀,二进制以0b或0B作为前缀。MATLAB以十进制整数来存储以这种方式定义的数。

对于以字面值方式输入的二进制或十六进制数,默认情况下MATLAB会以可表达它的最小位数的无符号整型来存储。例如,

可以看到,由于0x1FF超出了uint8所能表达的数值范围(0-255),MATLAB自动以uint16来存储变量B16。可以通过添加后缀来指定存储数字的整数类型。无符号整型的后缀为u8、u16、u32和u64;有符号整型的后缀为s8、s16、s32和s64。例如,

可以看出,上述第一条指令执行后,二进制数0b101010被以uint16进行了存储。需要注意的是,后缀所代表的整型必须足以容纳该数值,否则MATLAB会报错。上面的第二条指令试图用uint8来存储0x1FF,从报错信息可以看出这个十六进制数的位数超出了uint8能够表达的范围。

用bitget函数可以获取二进制数指定位置的位。该函数常用来获取二进制数的真值表。例如,执行如下代码:

可以依次列出A8的第8到第1位。需要注意的是,二进制数的位序由右侧算起,MATLAB中由1开始计数(c语言中由0开始计数)。

用bitset函数可以修改二进制数指定位的值。例如,将A的第3位设为1,并列出真值表:

MATLAB提供了专门的内置函数,以实现不同进制数之间的转换。例如,

对于二进制数,MATLAB提供专门的位运算函数,例如按位与(bitand)、按位或(bitor)、按位异或(bitxor)等。感兴趣的读者请doc Bit-Wise Operations进行深入学习。

(4)数值类型间的自动转换

如果一个表达式或数组中同时出现了多个不同数值类型的数据,MATLAB遵循如下原则自动转换数据类型:

  • double碰上single,结果为single,即浮点型混合向低精度看齐;
  • int只能与同类型int或double标量进行算术运算,结果为int。
  • 数组中出现多种int时,结果与最左侧的int相同,即数组中不同int向左看齐;

举例如下:

结果均为single。

报错信息显示,整型只能与同类整型或标量double进行混合运算。

注意:若计算结果超出了整型的表达范围,会被截断且不报错!

当不同整型的数据共同构成数组时,所产生的数组的数据类型遵循“向左看齐”的原则。例如,

请注意:第二条指令执行后,int16(500)由于被强制转换为int8,结果发生了溢出。再来看一个更为复杂的例子:

在这个例子中,数据类型转换的过程可以看作是分多个步骤完成的:首先,根据括号优先原则,类型转换函数会先将double类的数据转换为相应的数据类型。然后,根据“向低精度看齐”的原则,中括号内的double和single类数据都被转化成了最左侧的整型,即int16。最后,根据int类“向左看齐”的原则,所有的int类数据都被转化为了最左侧的int16。值得注意的是,其中的int8(200)并没有因为最后结果为int16而避免溢出,因为200是先被转换为int8,然后再被转换为int16的。

由于MATLAB会进行上述默认转换,不同数值类型数据混用时不但会导致计算结果的精度降低,而且容易导致难以察觉的错误,所以应该尽最大可能避免不同数值类型的数据混合使用。如非特殊需要(比如为MEX文件提供参数或为内存受限的单片机编程等),请用默认的double。这样不但计算精度高,而且由于避免了不必要的类型转换,程序的效率也更高,而且不容易出错。

除了不同的数值类型之间,当logical、char和string类数据与数值类型的数据一起运算或组成数组时也会被自动转换。例如,logical会被转化为double;char参与运算时会先被转化double,值为对应的Unicode码;char与数值组成数组时,结果为char,数值会被当作Unicode码转化为字符;string最为强势,无论是参与运算还是组成数组,结果都是string。这几种情况在程序中一般很少会故意用到。有兴趣的读者可以自行尝试。

郑重提示:在编程中,避免不同的数据类型混用是减少错误、提高程序性能的一个重要原则。



下一篇:轻松掌握MATLAB - 3.1 MATLAB的基本数据类型(3)

Tags:

最近发表
标签列表