Keil C51环境下64位浮点库的设计

2014-08-15 03:25李文昭王虹李庆
关键词:浮点数浮点尾数

李文昭,王虹,李庆

(1.河北大学 静电研究所, 河北 保定 071002;2.河北大学 电子信息工程学院, 河北 保定 071002)

随着电子技术的不断发展,在控制领域广泛使用的8051系列单片机也有了长足的发展,一些采用新技术的8051系列单片机不断出现,如NXP的LPC900系列[1]、STC的1T系列[2]、SiLabs的C8051F[3]系列等,这些产品的计算能力较传统8051系列单片机有了几十倍甚至上百倍的提升.曾经以控制为主的单片机,已有能力进行一些相对复杂的计算.然而目前针对8051的各种C语言编译器在数据类型上仅支持到float型变量[4].Keil作为目前国内使用最广泛的单片机集成开发环境,虽然支持了“double”关键字,但是其对double类型的变量仍然只是转为float型处理[4],实际计算精度并没有达到IEEE-754双精度浮点数的标准.针对目前C51编译器的不足,采用数组分部处理数据[5],在Keil C51环境下设计了符合IEEE-754双精度标准的浮点库,实现基本的四则运算,满足了在控制领域中需要进行高精度计算的特殊要求.

1 IEEE-754 标准

IEEE-754二进制浮点数算术标准定义了浮点数的表示格式,是目前广泛使用的浮点数格式标准,被多数CPU和浮点运算器采用.在IEEE-754标准中规定了单精度(32位)、扩展单精度(43位以上,不常用)、双精度(64位)和扩展双精度(79位以上)[6-8]4种浮点数的表示方式.IEEE-754二进制浮点数算术标准利用科学计数法来表示实数,一个符合IEEE-754的浮点数F被划分为3个字段,表示为如下形式:

F=(-1)S×M×2E,

(1)

其中,F是所表示的浮点数.S是符号位,占用1位二进制数宽度,E是阶码,也就是指数,用移码表示,在双精度浮点数中阶码占用11位二进制数宽度.M是尾数,通常都是规格化表示,即非“0”的有效位最高位总是“1”,然而在IEEE-754标准中是一个纯小数,有效位形式为“1.MMM…MMM”,在实际表示中整数位的“1”被省略,称为隐藏位,对于双精度浮点数而言M的宽度是52位二进制数,加上1位隐藏位共53位[6-8].由于

253= 9,007,199,254,740,992,

故双精度浮点数可以得到15~16位有效数字,常用的浮点数格式如表1所示.

表1 常用的浮点数表示格式

2 加法和减法运算设计

加减法运算是最基本的运算,因为A1-A2=A1+(-A2),故把加法运算和减法运算放在一起讨论.计算过程主要分为6步:1)0操作数检查;2)对阶;3)尾数相加;4)结果规格化;5)舍入处理;6)溢出处理.其中省略了2个和算法不相关的步骤,即进行第1步之后第2步之前需要分别把符号位、阶码、尾数从64位二进制串中提取出来;当进行完第6步后还要把这3部分组合成一个符合IEEE-754标准的64位二进制串.

1)0操作数检查.对2个操作数进行0检测,只要有1个操作数为0即可简化加法运算,此时只要返回另1个操作数,节省了运算时间.

2)比较阶码大小并完成对阶.如果2个操作数都不为0,则要进行阶码比较.当其中1个操作数的阶码远远大于另1个操作数的阶码时,也会在很大程度上简化运算.因为尾数的精度有限,当阶码之差大于尾数宽度时,说明其中1个操作数远大于另外1个,即使相加,结果也不会保留到那么高的精度,所以在这种情况下,会得到和0操作数检查几乎相同的运算时间消耗,只要返回较大的操作数就可以了.在64位计算中阶码之差要大于54才能简化运算.当阶码之差小于54时,就需要进行对阶和实际的加法计算.对阶操作时,要遵循小阶向大阶看齐的原则,否则会影响计算精度.具体的做法是先求出阶差,然后阶小的尾数进行右移位操作,每右移1位,阶码加1,直到2个操作数的阶码相等为止,此时右移的次数刚好等于移位前的阶差.

3)尾数相加.对阶完成后即可将2个尾数按定点加法运算规则进行运算.

4)结果规格化.当计算完毕,结果可能已经不是“1.XX…X”的形式,这时就需要进行规格化处理,即通过对尾数进行左移或右移操作并相应的修改阶码,使结果为规格化表示.

5)舍入.由于尾数的位数被限制为52位,所以在进行右移操作时可能造成低位数的丢失,这就需要进行舍入处理.本程序采用了较为精确的0舍1入法,当丢失的部分最高位为0时不作处理,当丢失的部位最高位为1时,则向最低位加1.

6)溢出处理.溢出分为4种情况:阶码上溢,一般认为是±∞;阶码下溢,一般将其认为是0;尾数上溢和尾数下溢,需要对尾数重新进行规格化处理[7].

3 乘法运算设计

浮点数的乘法相对于加法要复杂一些,2个浮点数相乘,乘积的阶码为2个乘数阶码之和,乘积的尾数为2个乘数尾数之积.例如,设2个浮点数A,B:A=2EA×MA,B=2EB×MB, 则A和B的乘积为

A×B=2(EA+EB)×(MA×MB).

(2)

因此,浮点数的乘法操作可以由4步完成:1)0操作数检查;2)阶码求和;3)尾数求积;4)尾数规格化并进行舍入处理.

1)0操作数检查.和加法操作一样,只要有一个操作数为0则可以直接返回0结果.

2)阶码求和.把2个乘数的阶码相加,结果为乘积的阶码,相加完毕后要进行溢出判断.溢出判断的方法是在原有移码的基础上再加上一位符号位,如果计算后此位为1则说明有溢出,溢出后,原符号位为0说明结果上溢;原符号位为1说明结果下溢.如果没有溢出,那么原符号位为0说明结果为负;原符号位为1说明结果为正.

3)尾数求积.尾数求积可采用定点乘法运算的原理.由于尾数加上隐藏位一共是53位,所以需要一个至少106位的空间存储乘积.而C51最大只支持2个16位数相乘,因此,需要把尾数分别存储在2个数组中,把尾数分为几段,进行计算的时候把每段和另一个尾数相乘,采用嵌套循环进行乘法处理然后再进行相加得到计算结果.求积计算是整个乘法运算中最耗时的操作.

4)尾数规格化并进行舍入处理.尾数求积后得到的结果受到长度限制,只能取前53位,然后进行舍入处理.舍入处理通常有2种方法:一种是截断处理,把剩余的低位数据全部作丢弃处理;另一种办法是0舍1入.同加法一样,为了提高计算精度,这里采用了0舍1入的处理方式.

4 除法的算法设计

除法是四则运算里面最复杂的,也是最耗时的[9-10].除法是乘法的逆运算,正如乘法可以用移位相加实现一样,除法可以通过一系列的移位相减实现.浮点除法的运算规则是

A/B=2(EA-EB)×(MA/MB).

(3)

商的阶码是两数阶码之差,商的尾数是两数尾数之商.因此,浮点数的除法操作和乘法一样可以由4步完成:1)0操作数检查;2)阶码求差;3)尾数求商;4)尾数规格化及舍入处理.

尾数求商是浮点除法运算的关键,原码除法通常采用“恢复余数法”和“加减交替法”.设计参考了恢复余数法并针对8051单片机计算速度慢的特点对循环减算法进行了改进优化,恢复余数法的特点是当除数为负时,需加上除数,将其恢复成原来的余数;循环减的特点是先判断是否够减,然后再进行相应的操作.而商的符号位由除数和被除数的符号进行异或运算得到,即

SIGN商=SIGN被除数⊕SIGN除数.

尾数的除法同样在Keil C51环境下遇到无法用一个变量表示的问题,解决的方法是用2个数组分别存储2个尾数,所以在用数组进行除法运算的时候要不断注意借位问题,以免造成计算错误.通过除数尾数对被除数尾数进行54次循环减之后,就得到了商.最后把计算好的阶码和符号位同商的尾数组合成标准的64位浮点数放在指定的存储空间,浮点除法计算就完成了.

5 程序验证

程序的运行效率是用户比较关心的问题,如果运行时间太长,那么64位浮点计算也就失去了意义.可以通过一组数据对加、乘、除分别测试,表2是经过多次测试得到的一组平均数据,可以看到3种运算的时间消耗都可以令人满意.

表2 3种运算的耗时对比

CPU:AT89C51,OSC CLOCK:12 MHz

由上表可以看出即使是12 MHz的普通8051单片机进行除法计算耗时也仅需40 ms左右,如果使用基于CIP-51核等一些新型的单片机那么3种计算的时间将会少于10 ms,由此看出8051系列的单片机完全能够胜任实时性要求不高的64位浮点计算.

当库函数完成以后,可利用Keil C51软件提供的库管理程序生成库文件,并为浮点库编写相应的头文件,以方便在以后的工程中调用.

6 结论

针对目前最广泛使用的Keil C51平台下无法进行双精度计算的实际问题,提出了一种可行的解决方案.在进行理论分析后,设计并实现了四则运算的64位双精度计算方法.

方案采用分部存储的方法,将较大的64位数据分成几个部分存储在内存空间,将各部分分别计算后再整合成需要的计算结果,其中大量使用指针,在充分分析时间和空间矛盾的基础上,针对8051核单片机有限的内存容量和较低的运算速度对程序进行了优化设计,和传统计算方法相比提高了程序运行效率,节省了存储空间.

在采用最普通的8051核单片机AT89C51的情况下,测试中加减法进行一次运算仅需要1.6 ms,乘法和除法单次运算也只需27.4 ms和36.2 ms,可以满足绝大多数实时性要求不高的工程需要,解决了目前Keil C51平台下无法进行高精度计算的难题,为8051系列单片机提供了更广泛的应用空间,同时避免了使用ARM等32位高端处理器带来的人力和财力支出.

参 考 文 献:

[1] 张立群,李铁才,连全斌.基于单片机P89LPC932A1的微功耗设计[J].自动化技术与应用,2006,25(11):30-33.

ZHANG Liqun, LI Tiecai, LIAN Quanbin. A low power design based on MCU P89LPC932A1[J]. Techniques of Automation & Applications,2006,25(11):30-33.

[2] 宏晶科技.宏晶科技STC12C5410AD系列单片机器件手册[EB/oL].〔2011-9-9〕(2013-1-23).http://www.stcncu.com/datasheet/stc/STC-AD-PDF/STC12C5410AD.PDF

[3] 钟磊,卢文壮,左敦稳,等.C8051F单片机的IAP系统设计与实现[J].微处理机,2009,03:9-11.

ZHONG Lei, LU Wenzhuang, ZUO Dunwen, et al. In-application programming system design and realization ofC8051F MCUs[J].Microprocessors,2009,03:9-11.(2013-1-23)〔2012-8-9〕www.keil.com

[4] KEIL Cx51 User’s Guide[EB/OL].Keil An ARM Company.2012.

[5] 狄光智,赵同林.数组实现高精度计算的方法研究[J].电脑编程技巧与维护,2009,10:126-127.

DI Guangzhi, ZHAO Tonglin.The study of high-precision computation using arrays[J]. Computer Programming Skills & Maintenance,2009,10:126-127.

[6] IEEE. IEEE Standard for Binary Floating-Point Arithmetic[S]. IEEE Std 754-2008:6-38

[7] 白中英.计算机组成原理[M].北京:科学出版社, 2008:22-71.

[8] BRYANT, O’HALLARON.深入理解计算机系统.[M].龚奕利,雷迎春,译.北京:机械工业出版社,2011:50-81.

[9] 陈森林,田华.快速浮点除法运算及其在单片机上的实现[J].陕西师范大学学报:自然科学版,2004,32(2):43-45.

CHEN Senlin, TIAN Hua. Rapid floating point division algorithm and its implementation on MCS-51 series single chip computer[J]. Journal of Shanxi Normal University: Natural Science Edition, 2004,32(2):43-45.

[10] 郭松,徐世亮,万里勇.巧用数组实现除法的高精度计算[J].计算机与信息技术, 2007,36:442,422.

GUO Song, XU Shiliang, WAN Liyong.Using array to achieve high precision of division[J].Science & Technology Information,2007,36:442,422.

猜你喜欢
浮点数浮点尾数
“改写”与“省略”三不同
LEO星座增强GNSS PPP模糊度浮点解与固定解性能评估
四种Python均匀浮点数生成方法
连续自然数及乘积的尾数和奇偶性的分析
基于浮点DSP的铁路FSK信号检测
2019年度下半年《启迪与智慧》上下半月刊、《幽默与笑话》上下半月刊、《拳击与格斗》上半月刊抽大奖中奖结果
在C语言中双精度浮点数线性化相等比较的研究
非精确浮点数乘法器设计
基于FPGA的浮点FIR滤波器设计
改进的Goldschmidt双精度浮点除法器