APP下载

基于C++ Builder 6.0的IEEE 754中单精度浮点数转换实现

2014-10-14翟振辉

现代电子技术 2014年20期
关键词:浮点尾数二进制

翟振辉

摘 要: IEEE 754标准规定了可以精确表示某一浮点型数据的单精度(常用)和双精度表示方法,这在许多对数据精度要求较高的场合得到广泛应用,而在数据通信过程中所有数据都是以十六进制打包和解析、二进制形式传输的,所以研究如何根据该标准把所要传输的浮点型数据编程转换成8位十六进制数据具有重要的实用意义。这里在分析和研究IEEE 754标准中浮点型数据单精度表示方式的基础上,结合Borland C++Builder 6.0可视化编程工具,阐述了如何把单精度浮点型数据转换成所需要的8位十六进制数,以及如何把8位十六进制数转换成单精度浮点类型数据,并实现显示。

关键词: IEEE 754标准; 十六进制数; 单精度浮点数; 可视化编程工具

中图分类号: TN911?34 文献标识码: A 文章编号: 1004?373X(2014)20?0027?04

Convert of floating?point data in IEEE754 based on C++ Builder6.0

ZHAI Zhen?hui1, OU Shi?feng1, LIU Ji?zhang1, ZHONG Quan?xiong2, GAO Ying1

(1. Institute of Optoelectronic Information, Yantai University, Yantai 264005, China; 2. Engineering Training Center, Yantai University, Yantai 264005, China)

Abstract: The single precision and double precision expressive methods which can accurately express a float?point data are stipulated in IEEE754 standard. They are widely in the field, in which the accuracy requirement is high. On the base of studying and analyzing the expression of the 32 bits floating?point, how to translate the floating?point data to the needed hexadecimal data, and how to translate the hexadecimal data to the floating?point data are elaborated in combination with the visual programming tools Borland C++ Builder 6.0, and the expression of the 32 bits floating?point data in the IEEE 754 standard. The data display was realized.

0 引 言

IEEE 754是最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用[1]。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number)、一些特殊数值(无穷与非数值(NaN))以及这些数值的“浮点数运算子”。它规定了4种表示浮点数值的方式:单精确度(32位元)、双精确度(64位元)、延伸单精确度(43位元以上,很少使用)与延伸双精确度(79位元以上,通常以80位元实做)。其中只有32位元模式有强制要求,其他都是选择性的[2]。

Borland C++ Builder是最知名的可视化C++应用程序开发工具之一,它易学易用的操作界面和功能强大的应用组件,可以让程序员快速建立各种应用程序[3]。Borland C++ Builder不仅继承了Delphi使用简便、功能强大、效率高等特点,而且它还结合C++语言所有的优点。C++ Builder可以说是至今最容易上手的Windows开发工具[4]。

目前可视化编程中应用IEEE处理整型数据到浮点型数据运算的研究还很少,本文侧重于实现将8位十六进制的数据转换成浮点型数据,应用于解析Modbus中RTU格式[5]通信所获得的浮点型数据,并编写了上位机可视化软件来显示。

1 转换算法介绍

1.1 浮点数保存格式

浮点型数据保存的格式[1]如表1所示。其中:S表示符号位;“1”表示负数;“0”表示正数;E代表偏移127的幂数,二进制阶码 =(EEEE EEEE)-127;M代表24位的尾数,存放在23个位中,只存储23位,最高位固定为1,此方法用最少的位数实现了较高的有效位数,提高了精度“0”是一个特定值,幂数是0,尾数也是0。

表1 浮点型数据保存的格式

1.2 十六进制数转换为浮点型数据

IEEE 754标准中的浮点保存值不是一个直接的格式,要把十六进制转换为一个浮点数,必须按照表1中所示的方式进行分开。这里又分为三种情况:

(1) E部分不全为0也不全为1的情况;

(2) E部分全部为0的情况;

(3) E部分全部为1的情况。

1.2.1 E部分不全为0也不全为1

以0xC1420000为例,先把0xC1420000写成表1中所示形式,如下:

SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

1100 0001 0100 0010 0000 0000 0000 0000

由上可以看出,此数是一个负数,二进制阶码=(1000 0010)-127 = 3,也就是实际的幂数。尾数是后面的二进制数100 0010 0000 0000 0000 0000,这是已存储的23位二进制,还有一位没有被存储的最高位,固定为1,所以整个尾数即:1100 0010 0000 0000 0000 0000则根据实际的幂数,浮点型数为:

[2k×i=023M×2i-23=-12.25] (1)

1.2.2 E部分全为0

这是一种非规格化的数据,此时k=1-(27-1)=-126,完整的位数部分为0MMM MMMM MMMM MMMM MMMM MMMM。以0x800BCAEF为例,先把0x800BCAEF写成表1中所示形式,如下:

SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

1000 0000 0000 1011 1100 1010 1110 1111

由上可以看出,此数是一个负数,二进制阶码k=1-127 =-126,也就是实际的幂数。

尾数是后面的二进制数000 1011 1100 1010 1110 1111,这是已存储的23位二进制,还有一位没有被存储的最高位,固定为1,所以整个尾数即:1000 1011 1100 1010 1110 1111,则根据实际的幂数,浮点型数为:[2k×i=023M×2i-23=-1.082 989 314 25e-39] (2)

1.2.3 E部分全部为1

如果E部分全为1,则系数k=28-1=127,此时又分两大类情况:

(1) 尾数是0的情况,这类情况下的数要么是正无穷大要么是负无穷大;

(2) 尾数不全为0的情况,根据IEEE 754标准,这类情况是表示的一个没有被定义的数,也就是不存在这样的数。

结合以上三部分的分析可得出计算步骤如下:

(1) 先判断十六进制数的最高位是否为1:若为1则是负数,若为0则是正数;

(2) 把该数右移23位并和0xFF相与,得到二进制数(EEEE EEEE);

(3) 把步骤(2)得到的二进制数(EEEE EEEE)减127得到二进制的最高位幂数(设为k);

(4) 把原数和0x7FFFFF相与得到不带最高位的尾数(MMM MMMM MMMM MMMM MMMM MMMM),然后再把得到的尾数的最高数置“1”,即得到完整的尾数:(1MMM MMMM MMMM MMMM MMMM MMMM);

(5) 在步骤(4)中得到的尾数的24位二进制数乘以2k并相加即是所求浮点数

2 编程实现

打开Borland C++ Builder 6.0,在空白的Form1上放置5个Edit控件,2个Label控件,1个按钮,布局Form上的控件并修改属性[3],如图1所示。

图1 软件设计界面

软件工作流程如图2所示。

3 仿真结果

把前面举例的数据0xC1420000进行计算,计算结果如图3所示。可由图3看出计算结果和第1.2.1中计算结果一致。

其次再把第1.2.2部分中所举的数据用软件进行计算,结果如图3所示。

可由图4看出,计算结果与第1.2.2部分中分析得出的结果一致。最后把第1.2.3部分中描述的情况用软件实现,结果如图5所示。

图5显示的是E部分全部为1且尾数部分不全为0的情况的计算结果。

图3 E部分不全为0也不全为1数据计算结果

图4 E部分全为0数据计算结果

图5 E部分全为1且尾数部分不全为0的数据计算

图6上半部分显示的是E部分全部为“1”且尾数部分全为“0”的一种计算。由于最高位为“1”,所以计算结果是负无穷大;下半部分是另外一种计算,由于最高位是“0”,所以计算结果是正无穷大。

图6 E部分全为1且尾数部分全为0的计算

另外本文又仿真了一组Modbus协议中表示温度的十六进制数据,转换成浮点型数据,仿真结果如图7所示。

图7 温度数据仿真结果

4 仿真结果验证

为了验证仿真结果的正确性,本文编写了从浮点型数据转换成十六进制数据的计算软件,将之前的数据进行一一验证,验证结果如图8、图9所示。

图8 数据仿真结果验证

图9 温度数据仿真结果验证

为确保本文中计算软件的无误计算,本文在-1 000~1 000之间随机取数进行了大量的数据转换计算实验,并随机记录了10组数据,如表2所示。

由表2中数据仿真结果及其验证可以看出本文中所编写的转换算法的精度是非常高的,能够满足高精度测量仪器的数据转换使用,而且可以看出小数点后保留的位数越多得出的结果越接近原始的数据。

5 结 论

利用Borland C++Builder 6.0编程开发环境完成的十六进制整型数据转换为浮点型数据的软件实现了从整型数据到浮点型数据的转换计算,经过二次开发该软件可被用于Modbus通信协议中高精度浮点型数据的传输打包、解析和显示。另外,本文也完成了从浮点型数据到十六进制整型数据的转换编程及仿真显示。

参考文献

[1] Microprocessor Standards Committee of the IEEE Computer Society. IEEE Std754?1985 IEEE standard for floating?point arithmetic [S]. USA: Microprocessor Standards Committee of the IEEE Computer Society, 1985.

[2] 程展鹏.Borland C++ Builder 6 应用开发技术解析[M].北京:清华大学出版社,2003.

[3] 谭浩强.C语言程序设计[M].4版.北京:清华大学出版社,2010.

[4] 吴逸贤,吴目成.精彩C++ Builder 6程序设计[M].北京:科学出版社,2003.

[5] 全国工业过程测量和控制标准化技术委员会.GB/T19582?2008 Modbus通信协议[S].北京:中国标准出版社,2008.

[6] 陈鹏,蔡雪梅.NIOS浮点运算定制指令的实现[J].现代电子技术,2011,34(10):166?168.

[7] 唐小明,张涛,王贞杰,等.一种新的基于FPGA的数据格式转换方法[J].现代电子技术,2011,34(16):110?112.

[8] 谢跃雷,陈敏.粒子滤波算法中浮点指数函数的FPGA设计实现[J].现代电子技术,2008,31(18):119?121.

Keywords: IEEE 754 standard; hexadecimal number; floating?point data with single precision; visual programming tool

由上可以看出,此数是一个负数,二进制阶码=(1000 0010)-127 = 3,也就是实际的幂数。尾数是后面的二进制数100 0010 0000 0000 0000 0000,这是已存储的23位二进制,还有一位没有被存储的最高位,固定为1,所以整个尾数即:1100 0010 0000 0000 0000 0000则根据实际的幂数,浮点型数为:

[2k×i=023M×2i-23=-12.25] (1)

1.2.2 E部分全为0

这是一种非规格化的数据,此时k=1-(27-1)=-126,完整的位数部分为0MMM MMMM MMMM MMMM MMMM MMMM。以0x800BCAEF为例,先把0x800BCAEF写成表1中所示形式,如下:

SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

1000 0000 0000 1011 1100 1010 1110 1111

由上可以看出,此数是一个负数,二进制阶码k=1-127 =-126,也就是实际的幂数。

尾数是后面的二进制数000 1011 1100 1010 1110 1111,这是已存储的23位二进制,还有一位没有被存储的最高位,固定为1,所以整个尾数即:1000 1011 1100 1010 1110 1111,则根据实际的幂数,浮点型数为:[2k×i=023M×2i-23=-1.082 989 314 25e-39] (2)

1.2.3 E部分全部为1

如果E部分全为1,则系数k=28-1=127,此时又分两大类情况:

(1) 尾数是0的情况,这类情况下的数要么是正无穷大要么是负无穷大;

(2) 尾数不全为0的情况,根据IEEE 754标准,这类情况是表示的一个没有被定义的数,也就是不存在这样的数。

结合以上三部分的分析可得出计算步骤如下:

(1) 先判断十六进制数的最高位是否为1:若为1则是负数,若为0则是正数;

(2) 把该数右移23位并和0xFF相与,得到二进制数(EEEE EEEE);

(3) 把步骤(2)得到的二进制数(EEEE EEEE)减127得到二进制的最高位幂数(设为k);

(4) 把原数和0x7FFFFF相与得到不带最高位的尾数(MMM MMMM MMMM MMMM MMMM MMMM),然后再把得到的尾数的最高数置“1”,即得到完整的尾数:(1MMM MMMM MMMM MMMM MMMM MMMM);

(5) 在步骤(4)中得到的尾数的24位二进制数乘以2k并相加即是所求浮点数

2 编程实现

打开Borland C++ Builder 6.0,在空白的Form1上放置5个Edit控件,2个Label控件,1个按钮,布局Form上的控件并修改属性[3],如图1所示。

图1 软件设计界面

软件工作流程如图2所示。

3 仿真结果

把前面举例的数据0xC1420000进行计算,计算结果如图3所示。可由图3看出计算结果和第1.2.1中计算结果一致。

其次再把第1.2.2部分中所举的数据用软件进行计算,结果如图3所示。

可由图4看出,计算结果与第1.2.2部分中分析得出的结果一致。最后把第1.2.3部分中描述的情况用软件实现,结果如图5所示。

图5显示的是E部分全部为1且尾数部分不全为0的情况的计算结果。

图3 E部分不全为0也不全为1数据计算结果

图4 E部分全为0数据计算结果

图5 E部分全为1且尾数部分不全为0的数据计算

图6上半部分显示的是E部分全部为“1”且尾数部分全为“0”的一种计算。由于最高位为“1”,所以计算结果是负无穷大;下半部分是另外一种计算,由于最高位是“0”,所以计算结果是正无穷大。

图6 E部分全为1且尾数部分全为0的计算

另外本文又仿真了一组Modbus协议中表示温度的十六进制数据,转换成浮点型数据,仿真结果如图7所示。

图7 温度数据仿真结果

4 仿真结果验证

为了验证仿真结果的正确性,本文编写了从浮点型数据转换成十六进制数据的计算软件,将之前的数据进行一一验证,验证结果如图8、图9所示。

图8 数据仿真结果验证

图9 温度数据仿真结果验证

为确保本文中计算软件的无误计算,本文在-1 000~1 000之间随机取数进行了大量的数据转换计算实验,并随机记录了10组数据,如表2所示。

由表2中数据仿真结果及其验证可以看出本文中所编写的转换算法的精度是非常高的,能够满足高精度测量仪器的数据转换使用,而且可以看出小数点后保留的位数越多得出的结果越接近原始的数据。

5 结 论

利用Borland C++Builder 6.0编程开发环境完成的十六进制整型数据转换为浮点型数据的软件实现了从整型数据到浮点型数据的转换计算,经过二次开发该软件可被用于Modbus通信协议中高精度浮点型数据的传输打包、解析和显示。另外,本文也完成了从浮点型数据到十六进制整型数据的转换编程及仿真显示。

参考文献

[1] Microprocessor Standards Committee of the IEEE Computer Society. IEEE Std754?1985 IEEE standard for floating?point arithmetic [S]. USA: Microprocessor Standards Committee of the IEEE Computer Society, 1985.

[2] 程展鹏.Borland C++ Builder 6 应用开发技术解析[M].北京:清华大学出版社,2003.

[3] 谭浩强.C语言程序设计[M].4版.北京:清华大学出版社,2010.

[4] 吴逸贤,吴目成.精彩C++ Builder 6程序设计[M].北京:科学出版社,2003.

[5] 全国工业过程测量和控制标准化技术委员会.GB/T19582?2008 Modbus通信协议[S].北京:中国标准出版社,2008.

[6] 陈鹏,蔡雪梅.NIOS浮点运算定制指令的实现[J].现代电子技术,2011,34(10):166?168.

[7] 唐小明,张涛,王贞杰,等.一种新的基于FPGA的数据格式转换方法[J].现代电子技术,2011,34(16):110?112.

[8] 谢跃雷,陈敏.粒子滤波算法中浮点指数函数的FPGA设计实现[J].现代电子技术,2008,31(18):119?121.

Keywords: IEEE 754 standard; hexadecimal number; floating?point data with single precision; visual programming tool

由上可以看出,此数是一个负数,二进制阶码=(1000 0010)-127 = 3,也就是实际的幂数。尾数是后面的二进制数100 0010 0000 0000 0000 0000,这是已存储的23位二进制,还有一位没有被存储的最高位,固定为1,所以整个尾数即:1100 0010 0000 0000 0000 0000则根据实际的幂数,浮点型数为:

[2k×i=023M×2i-23=-12.25] (1)

1.2.2 E部分全为0

这是一种非规格化的数据,此时k=1-(27-1)=-126,完整的位数部分为0MMM MMMM MMMM MMMM MMMM MMMM。以0x800BCAEF为例,先把0x800BCAEF写成表1中所示形式,如下:

SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM

1000 0000 0000 1011 1100 1010 1110 1111

由上可以看出,此数是一个负数,二进制阶码k=1-127 =-126,也就是实际的幂数。

尾数是后面的二进制数000 1011 1100 1010 1110 1111,这是已存储的23位二进制,还有一位没有被存储的最高位,固定为1,所以整个尾数即:1000 1011 1100 1010 1110 1111,则根据实际的幂数,浮点型数为:[2k×i=023M×2i-23=-1.082 989 314 25e-39] (2)

1.2.3 E部分全部为1

如果E部分全为1,则系数k=28-1=127,此时又分两大类情况:

(1) 尾数是0的情况,这类情况下的数要么是正无穷大要么是负无穷大;

(2) 尾数不全为0的情况,根据IEEE 754标准,这类情况是表示的一个没有被定义的数,也就是不存在这样的数。

结合以上三部分的分析可得出计算步骤如下:

(1) 先判断十六进制数的最高位是否为1:若为1则是负数,若为0则是正数;

(2) 把该数右移23位并和0xFF相与,得到二进制数(EEEE EEEE);

(3) 把步骤(2)得到的二进制数(EEEE EEEE)减127得到二进制的最高位幂数(设为k);

(4) 把原数和0x7FFFFF相与得到不带最高位的尾数(MMM MMMM MMMM MMMM MMMM MMMM),然后再把得到的尾数的最高数置“1”,即得到完整的尾数:(1MMM MMMM MMMM MMMM MMMM MMMM);

(5) 在步骤(4)中得到的尾数的24位二进制数乘以2k并相加即是所求浮点数

2 编程实现

打开Borland C++ Builder 6.0,在空白的Form1上放置5个Edit控件,2个Label控件,1个按钮,布局Form上的控件并修改属性[3],如图1所示。

图1 软件设计界面

软件工作流程如图2所示。

3 仿真结果

把前面举例的数据0xC1420000进行计算,计算结果如图3所示。可由图3看出计算结果和第1.2.1中计算结果一致。

其次再把第1.2.2部分中所举的数据用软件进行计算,结果如图3所示。

可由图4看出,计算结果与第1.2.2部分中分析得出的结果一致。最后把第1.2.3部分中描述的情况用软件实现,结果如图5所示。

图5显示的是E部分全部为1且尾数部分不全为0的情况的计算结果。

图3 E部分不全为0也不全为1数据计算结果

图4 E部分全为0数据计算结果

图5 E部分全为1且尾数部分不全为0的数据计算

图6上半部分显示的是E部分全部为“1”且尾数部分全为“0”的一种计算。由于最高位为“1”,所以计算结果是负无穷大;下半部分是另外一种计算,由于最高位是“0”,所以计算结果是正无穷大。

图6 E部分全为1且尾数部分全为0的计算

另外本文又仿真了一组Modbus协议中表示温度的十六进制数据,转换成浮点型数据,仿真结果如图7所示。

图7 温度数据仿真结果

4 仿真结果验证

为了验证仿真结果的正确性,本文编写了从浮点型数据转换成十六进制数据的计算软件,将之前的数据进行一一验证,验证结果如图8、图9所示。

图8 数据仿真结果验证

图9 温度数据仿真结果验证

为确保本文中计算软件的无误计算,本文在-1 000~1 000之间随机取数进行了大量的数据转换计算实验,并随机记录了10组数据,如表2所示。

由表2中数据仿真结果及其验证可以看出本文中所编写的转换算法的精度是非常高的,能够满足高精度测量仪器的数据转换使用,而且可以看出小数点后保留的位数越多得出的结果越接近原始的数据。

5 结 论

利用Borland C++Builder 6.0编程开发环境完成的十六进制整型数据转换为浮点型数据的软件实现了从整型数据到浮点型数据的转换计算,经过二次开发该软件可被用于Modbus通信协议中高精度浮点型数据的传输打包、解析和显示。另外,本文也完成了从浮点型数据到十六进制整型数据的转换编程及仿真显示。

参考文献

[1] Microprocessor Standards Committee of the IEEE Computer Society. IEEE Std754?1985 IEEE standard for floating?point arithmetic [S]. USA: Microprocessor Standards Committee of the IEEE Computer Society, 1985.

[2] 程展鹏.Borland C++ Builder 6 应用开发技术解析[M].北京:清华大学出版社,2003.

[3] 谭浩强.C语言程序设计[M].4版.北京:清华大学出版社,2010.

[4] 吴逸贤,吴目成.精彩C++ Builder 6程序设计[M].北京:科学出版社,2003.

[5] 全国工业过程测量和控制标准化技术委员会.GB/T19582?2008 Modbus通信协议[S].北京:中国标准出版社,2008.

[6] 陈鹏,蔡雪梅.NIOS浮点运算定制指令的实现[J].现代电子技术,2011,34(10):166?168.

[7] 唐小明,张涛,王贞杰,等.一种新的基于FPGA的数据格式转换方法[J].现代电子技术,2011,34(16):110?112.

[8] 谢跃雷,陈敏.粒子滤波算法中浮点指数函数的FPGA设计实现[J].现代电子技术,2008,31(18):119?121.

Keywords: IEEE 754 standard; hexadecimal number; floating?point data with single precision; visual programming tool

猜你喜欢

浮点尾数二进制
“改写”与“省略”三不同
LEO星座增强GNSS PPP模糊度浮点解与固定解性能评估
用二进制解一道高中数学联赛数论题
连续自然数及乘积的尾数和奇偶性的分析
有趣的进度
基于浮点DSP的铁路FSK信号检测
2019年度下半年《启迪与智慧》上下半月刊、《幽默与笑话》上下半月刊、《拳击与格斗》上半月刊抽大奖中奖结果
二进制在竞赛题中的应用
基于FPGA的浮点FIR滤波器设计
改进的Goldschmidt双精度浮点除法器