
3.3 数值
数值类型(Numeric)是程序设计中最为常用的数据类型,LabVIEW提供了多种针对数值类型的操作如图3-11所示,包括:
(1)算术运算:加、减、乘、除、绝对值、平方、平方根等。
(2)类型转换:各种类型数据之间的转换。
(3)数值处理:位操作、字节处理等。
(4)复数运算。
(5)一些常用的数据变换,如电压至摄氏度的变换等。
(6)一些常量,如π、e等。
由于基本的算数较为常用,且LabVIEW的图形函数非常直观易用,因此这里不做详细介绍,如果有问题,读者可参阅labVIEW的在线帮助。
设计人员在选择数值控件时,必须考虑程序处理所需数值的大小、范围、精度,并要兼顾数值在计算机内部的存储空间大小,选择效率最高的控件。一般来说,数据类型的一致性最重要。LabVIEW为每种不同的数据表示方法分配独立的存储空间,使用不同的数据类型需要增加额外的编程、数据处理、缓冲和存储空间的占用。优化程序的性能和内存使用是程序设计人员自始至终的追求,一致的数据类型不但能减少编程工作量,还能确保程序的效率和可靠性。

图3-11 LabVIEW数值操作函数集
如果需要在数据存储效率和内存消耗之间做出权衡,则一般选择通过数据结构的一致性来降低内存消耗。这是因为内存访问时间是普遍存在的等待时间,而作为珍贵资源的内存却禁不起折腾。例如为一个有4096个元素的DBL型数组分配内存和为一个同样大小的I16型数组分配内存的时间相当,但如果将一个I16型数组再转换成DBL型则需要消耗大量的内存缓冲。当然,在程序中数据存储的次数越多,对程序性能的负面影响越大。
下面来看一个实际例子。在串行通信中,通常需要将8位无符号数组元素两两组合为16位整型,然后参与后续计算,图3-12给出了一种处理方法。在该例子中,程序先获取类型为8位无符号整型(U8)数组的长度,除以2之后得出循环处理次数N。随后使用For循环,将数组中的元素两两组合并转换为16位有符号整型(I16)数并组合成新数组(新数组长度减半),For循环结束后将新数组中各元素均放大1.5倍输出。由于新数组为I16类型,而放大因子是双精度浮点型(DBL),因此数组必须在乘法计算前,被强制转换成双精度浮点类型,这使得原来长度为2字节的每个数组元素变为8字节,存储缓冲增加了4倍。

图3-12 U8数组元素两两组合为I16元素后参与计算的例子
如果全盘考虑,在For循环中直接将U8类型的2字节转换为双精度浮点型数组,则可避免后续因数组类型的强制转换而带来的大量内存消耗。当然,将2字节转换为浮点数所需的额外内存必不可少,但相对强制类型转换所需的大量缓冲不值一提。
不同的数据类型转换可归纳为“强制转换”(Coercion)和“显式转换”两类。当进行强制转换时,强制转换点(红色小圆点)会出现在输入参数节点上。一般将两种不同类型的数据连接在一起时会出现强制转换现象,LabVIEW会对不同的参数进行转换以适合运算。例如图3-13中的乘法运算需要双精度浮点数输入,当输入16位无符号整型数据时,LabVIEW必须对数据进行强制转换后才进行计算。强制类型转换往往意味着消耗较多存储空间和运行时间,这就要求在设计VI时尽可能保证传递的数据一致。显式转换通过LabVIEW数据类型转换函数实现,LabVIEW提供丰富的数据类型转换函数供设计人员使用。

图3-13 对图3-12的例子优化后的程序
无论是强制转换还是显式转换,LabVIEW均遵循以下数据类型的转换规律。
1.整型转为浮点数
通过“整型转为浮点数”(Integer to floating-point number),LabVIEW将无符号或带符号整型数转换为最近似的浮点数。
2.浮点数转换为整型
通过“浮点数转换为整型”(Floating-point number to Integer),LabVIEW按照“四舍五入法”或“去尾法”的原则进行转换。例如对于连接至For循环次数的浮点数,如果其值为4.5,则按照去尾法取值4而非5;而运算时如果涉及浮点数转换为整型数,则按照“四舍五入”的原则。
3.将枚举数当无符号整型看待
通过“将枚举数当无符号整型看待”(Enums as unsigned integers),LabVIEW按照范围将枚举类型匹配至适当的整数类型。当要转换的数在所定义枚举类型的范围内时,采用四舍五入的原则,如果超出范围,则按就近原则取所定义枚举类型范围的上限或下限。例如枚举类型范围为0~7,当需要将浮点数5.2转换为枚举数时,其值为5;对5.6转换时,其值为6;对-2.8转换时,其值为0;对10.8转换时,其值为7。
4.整型数之间的转换
LabVIEW可以实现“整型数之间的转换”(Integer to integer),如果转换源类型比目标类型范围小,则对有符号整型数来说,LabVIEW会用符号位补充所有多余位,对无符号整型来说,将在多余位补0;如果转换源类型比目标类型范围大,则仅取低位部分。表3-3以-2为例给出了在U8/I8/U16/I16之间相互转换的情况。
表3-3 以U8/I8/U16/I16格式显示的-2值

5.整型、浮点型或定点类型到定点类型之间的转换
在进行整型、浮点型或定点类型到定点类型之间的转换(Integer, floating-point, or fixed-point number to fixed-point number)时,对超出范围的数分别取上限或下限。
虽然设计人员可以在不同数值类型之间进行转换,但在设计时还是经常会用I32来代表整型数,用双精度浮点数代表浮点数。单精度浮点数基本上不会节省太多空间和处理时间,还经常会溢出,扩展的浮点数只在必要时才使用。当连接多个不同类型的数据到一个函数时,通常LabVIEW会先按照精度较高、范围较大的类型作为目标来转换所有数据类型后再做计算。
在LabVIEW的数值操作函数集中还包括一些底层的字节和位处理的一些函数,这些函数对设计与硬件相关的一些应用极其有用。例如在设计与单片机通信的程序或数据报文处理的程序时,使用它们非常灵活。