用VB编程实现IEEE 754浮点数与十六进制格式转换
2017-12-19刘青青
刘青青
摘 要: IEEE浮点数算术标准(IEEE 754)是最广泛使用的浮点数运算标准,为许多CPU与浮点运算器DSP所采用。而在实际工程应用上,比如计算机串口通讯中数据都是以十六进制数据打包、解析和传输的,所以研究如何根据该标准把所要传输的浮点型数据编程转换成十六进制数据具有重要的实用意义。这里在分析和研究了IEEE 754标准中浮点型数据表示方式和存储方式的基础上,结合Visual Basic 6.0 可视化编程工具,阐述了如何把单/双精度浮点型数据转换成十六进制数,以及逆过程把十六进制数转换成单/双精度浮点类型数据的简便方法。
关键词: IEEE 754 标准;十六进制数;单精度浮点数;VB
0 引言
IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43位以上)与延伸双精确度(79位元以上,通常以80位元实做)。只有32位模式有强制要求,其他都是选择性的。大部分编程语言都有提供IEEE格式与算术,但有些将其列为非必要的。例如,IEEE 754问世之前就有的C语言。IEEE754标准包括IEEE算术,但不算作强制要求(VB语言的single通常是指IEEE单精度,而double是指IEEE双精度)。
VB是Visual Basic 的简称,在编程语言中属于较简单易于学习掌握的一类,由微软公司开发研制,已经得到了广泛的应用,VB主要拥有 GUI 系统( 即图形用户界面) 以及RAD系统( 快速应用程序开发) 等。VB编程语言在开发时,依据的原则就是为了方便程序开发人员使用,所以 VB语言是面向对象的基于窗口可视化的编程语言,在组件内已经定义了部分默认的方法和属性,也可以通过增加代码的方式来指定组建方法和属性,方便编程人员使用。在 VB编程语言中,对一个对象的描述主要通过描述事件、方法和属性的方式就可以完成。
1 转换方法阐述
浮点型数据保存的格式如表 1 所示。其中:S 表示符号位;“1”表示负数;“ 0”表示正数;E 代表偏移 127 的幂数,二进制阶码 =(EEEE EEEE)-127;M 代表 24 位的尾数,存放在 23 个位中,只存储 23 位,最高位固定为 1,此方法用最少的位数实现了较高的有效位数,提高了精度“0”是一个特定值,幂数是0,尾数也是 0。
采用标准算法,需要对数据按位进行运算,这里不再介绍。本文采用一种创新的思路,可以更简便的实现数据转换。
这里首先以单精度浮点数为例进行分析,例如把浮点数112.3456789赋值给一个单精度变量F1,那么这个浮点数F1在计算机内存中占用4个字节存储单元,每字节8位。为提高可读性,我们把变量F1在内存单元中的存储格式用图形化为图1所示。
再定义一个十六进制数组AA,并使得数组首个数据元素AA(0)的内存地址映射为0x1000,也就是与浮点数F1的起始存储地址相同,那么数组AA的每个元素就对应该内存地址起始的4个存储单元,由此就可以实现单精度浮点数F1与16进制数组AA的转换了。
双精度数据也可以采用这种方法,只不过双精度数据所占用的存储单元为8个字节,就不在赘述了。
由于在VB6.0编程语言的局限性,无法对变量和数组的内存地址直接进行映射,因此无法直接从变量F1得到数据AA。但VB6.0可以利用API函数copymemory,將变量F1内存起始地址的数据复制到数组AA的内存起始地址上,也可以反过来将数组AA内存起始地址的数据复制到变量F1的内存起始地址上,从而就可以实现单精度浮点数与十六进制数据的转换。
2 编程实现
打开VB6.0编程软件,新建一个工程,如图2所示,在窗体form1上放置文本框Text1、文本框数组Text2和按钮Command1,用来将单精度浮点数转换为十六进制数。再放置文本框数组Text3、文本框Text4和按钮Command2,用来将十六进制数转换为单精度浮点数。
源程序如下:
Private Declare Sub copymemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal length As Long)
'声明API函数,它有3个参数, Destination代表目标内存地址,Source代表源内存地址,length代表需要复制的字节数
Private Sub Command1_Click()
Dim F1 As Single ‘定义一个单精度浮点数变量
Dim AA(4) As Byte ‘定义一个十六进制数组变量
F1 = Val(Text1) ‘将文本框中的数赋值给变量F1
copymemory ByVal VarPtr(AA(0)), ByVal VarPtr(F1), 4
‘把浮点数F1所在内存的4个字节赋值给数组AA
For i = 0 To 3
Text2(i) = Hex(AA(i)) ‘将数据按从低到高的顺序以十六进制显示出来
Next i
End Sub
Private Sub Command2_Click()
Dim F2 As Single ‘定义一个单精度浮点数变量
Dim BB(4) As Byte ‘定义一个十六进制数组变量
BB(0) = "&h" + Text3(0) ‘将十六进制数据赋值给数组BB
BB(1) = "&h" + Text3(1)
BB(2) = "&h" + Text3(2)
BB(3) = "&h" + Text3(3)
copymemory ByVal VarPtr(F2), ByVal VarPtr(BB(0)), 4
‘把数组BB所在内存的4个字节赋值给浮点数F2
Text4 = F2 ‘将转换后的浮点数显示在文本框里
End Sub
最后,按F5运行该程序,计算结果如图3所示。
3 结论
本文利用Visual Basic 6.0编程开发环境完成了十六进制整型数据和单精度浮点型数据相互转换,可被用于串口通信中单精度浮点型数据的传输打包、解析和显示。此方法对于双精度浮点数的转换也同样有效,只需要将程序中的4字节数组定义为8字节数组,并将copymemory函数的第三个参数由4改为8即可。
参考文献
[1] 程展鹏.Borland C++ Builder 6 应用开发技术解析[M].北京:清华大学出版社, 2003.
[2] 黄艺坤.VB 编程语言在软件开发中的应用探究[J].建材与装饰,2012,8: 173.
[3] 丁龙.基于 VB 的定制软件开发与应用[J]. 软件开发与设计,2012,12: 23 - 24.