80C196系列单片机高精度浮点运算及数制转换子程序
内容导读:
80C196系列单片机高精度浮点运算及数制转换子程序珠海志美电子公司张克彦摘要提供一组80C196单片机高精度浮点运算及数制转换子程序。阶码采用1字节移码,尾数采用双字节原码,精度为91[]2位十进制数据。在16MHz时钟下,32位精度乘法及28位精度除法均不超过40μs,32位精度除法不超过80μs。程序有四舍五入功能及溢出判断功能。文中提供程序清单,可直接调用,为快速函数计算提供了有力支持。关键词80C196浮点运算数制转换 图180C196系列单片机常用于智能仪表、机电控制系统,经常会遇到一些数值计算,特别是一些快速函数计算的问题。本文介绍的运算子程序及数制转换子程序为80C196系列单片机用户提供快速函数计算方面的有力支持。在高精度浮点运算中以牛顿二项式展开法将双字相除转化为双字除以字,字加、减、乘。以模拟手算实现浮点数开平方,9位十进制精度不超过350μs。以将浮点数压缩到快速收敛区间,再进行牛顿迭代(最多只3次)实现快速开平方,6位十进制精度不超过145μs,9位十进制精度不超过250μs。本浮点数格式兼容IEEE标准,如必须用3字节尾数,应占用双字中高位3字节,而将最末字节清除,并调用FPDI2子程序作除法。一、 浮点数阶码和尾数的选择 1 阶码的选择,移码 1个8位二进制计数器,我们让它不停地计数,其状态就在00H~0FFH间周而复始地变化,可计256个数。若把这256个数看作有符号数:最高位为符号位,0为正,1为负,并认为在7FH与80H之间产生间断,则得到补码:00H=0,40H=+64,7FH=+127,80H=-128,0C0H=-64和0FFH=-1,如图1(a)所示。补码的优点为加减运算方便(符号位可参与运算),可直接使用访问V标志位的指令来判断溢出及比较并符合习惯等。以补码作为浮点数的阶码,给浮点运算带来一定方便。若把图1(a)中0FFH与0间视为间断,令00H=0,01H=-127,40H=-64,7FH=-1,80H=0,0C0H=+64及0FFH=+127,如图1(b)所示,即把最高位也视为符号位,但与补码相反:1为正,0为负,则得到移码。移码作为浮点数的阶码,有如下优点:(1) 阶码为零是浮点数等于零的充要条件,即阶码为零,浮点数亦为零;反过来浮点等于零,其阶码也等于零,而非零数不能具有零阶码。运算过程中若出现阶码变为零(尾数绝对值不为零),当作溢出处理。若出现尾数等于零(减法运算时),则将阶码清为零,表示得到了浮点数零,体现了阶码最小,数模(绝对值)最小的事实。(2) 从图1(a)与图1(b)的对比中看出,移码的零点是补码的间断点;反之,补码的零点也是移码的间断点(相差80H)。移码与其对应的补码之间有如下简单关系:移码=补码±80H。这也是浮点数阶码与阶之间的换算公式。移码与补码一样符合求补规律。(3) 由移码特点,以及80C196单片机加上原码与减去补码对进位位影响效果相同之特点,很容易做移码加减法。移码之和(或差)加上(或减去)80H,即为和(或差)的移码。具体过程如下:移码求和(差)如有进位,将和(差)加上80H,如还有进位,即为溢出(此时C,V标志位同时置位),无进位则得到和(差)的移码;移码求和(差)无进位,将和(差)减去80H,如溢出标志位V置位,或Z标志位置位,也为溢出,否则得到和(差)之移码。移码相减亦可先将减数求补,变为加法运算,减原和加补对进位影响相同。移码经以上运算之后,测试V,Z这两个标志位,如有1个或2个都置位,转溢出处理。(4) 可使检测浮点运算溢出的操作简化。计算结果可能产生非规格化浮点数,这时必须对结果左规或右规处理:左规一位,阶码减1,阶码从01H变为00H为溢出;右规一位,阶码增1,阶码从0FFH变为00H也为溢出。溢出统归为阶码变为零。(5) 移码可看作是无符号数,按00H到0FFH从小到大排列。阶码排序与阶值排序相一致,故可按无符号数(绝对值)比较阶之大小。因使浮点数之模与阶码之间具有良好的协调性、有序性,因此优于采用补码作为阶码。 2 尾数的选择,浮点数规格化尾数可选为原码或补码,以补码作为尾数,加减运算方便。选原码作尾数,可选用在最高位上附数符,不占用数据位的方法,因而具有最高精度。这时,浮点数的规格化必须以其绝对值进行。规格化过程是使非零浮点数之最高有效位变为1(左规,同时,阶码减去左移位数),或使最高有效位恢复原位(右规,阶码增1)。负数保留高位1,正数则将其清除(必须指出,对尾数这样规定后,阶码只能选用移码!)。这种浮点数加、减、乘、除运算都是对绝对值进行的。运算前处理、保存数符,恢复正数尾数的最高位1;运算后配置结果数符。具有乘、除运算方便,求补也方便(只须求反数符)等特点。本文中所采用的浮点数格式如下:阶码1字节移码,尾数4字节原码,如图1(c)所示。精度为32位,数模范围为5.8×10-39~1.7×1038,兼容IEEE标准。二、 浮点运算和浮点数制转换子程序的说明 1 浮点运算子程序的入出口条件浮点运算共有7个子程序,它们是:浮点加法子程序FPAD;浮点减法子程序FPSU;浮点乘法子程序FPMU;浮点除法子程序FPDI/FPDI2,模拟手算开平方子程序FPSQ(尾数28位有效)和牛顿迭代快速开平方子程序FSQR。入口时,将含“被”意义的第1操作数的阶码放在2DH字节型单元内,而尾数放在双字型单元24H内,27H为高位字节。将第2操作数之阶码放在2CH字节型单元内,而尾数放在双字型单元28H内。对于单操作数(浮点数开平方)则占据第2操作数之存放位置。运算结果一律占据第2操作数位置。如希望保留原始数据或中间结果,应在运算之前将其转入内存保留。浮点数比较大小子程序CMPR的入口条件与浮点减法子程序FPSU相同,但不做浮点运算,只比较被减数和减数的大小。比较结果由Z,C两标志位来判断。 2浮点数制转换子程序的入出口条件(1) 浮点数十翻二子程序的入出口条件入口时,十进制浮点数之尾数放在2CH~28H共5个字节内。2CH为高位字节,共10位BCD码,小数点在高位字节之前,尾数取值范围为0.1~1×10-9,2DH单元内为阶,两位BCD码;2EH单元内为阶符;2FH单元内为数符。0表示正,0FFH表示负。转换结果为规格化浮点数,占据第2操作数位置。(2) 浮点数二翻十子程序的入出口条件入口时,十进制浮点数占据第2操作数之位置。出口时,十进制浮点数之尾数放在2CH~28H共5个字节中,为9位BCD码。其中2CH为尾数整数部分,1位BCD码,其值为1~9;2BH~28H中存放尾数之小数部分,8位BCD码。十进制浮点数之阶码放在2DH单元内,2位BCD码。42H单元内存放阶符,43H单元内存放数符。00H表示正,非0表示负。 3 浮点数比较大小子程序CMPR的说明在执行浮点运算之前,有时要通过比较来判断2个浮点数之大小或相等,而且不能破坏2个浮点数。以往都是用浮点减法代替比较,以差的正负或等于0来判断比较结果。但浮点减法会破坏操作数,要做许多多余的工作,如对阶、规格化等,浪费时间,而CMPR没有以上弊端,速度快。因采用移码作阶码,原码作尾数,阶码和尾数皆可按绝对值比较大小。比较过程中不恢复正数尾数最高位1。因正数尾数相比较,相当于已各自减去了同一常数,对比较结果无影响。而正数与负数比较时,正是利用正数尾数最高位为零而负数尾数最高位为1这一特征,又因阶码与阶有如下关系:阶码=阶+80H,故可用阶码绝对值相比较代替阶相比较。浮点数的“重头”在阶码部分,同号数比较时先比较阶码,阶码相等时才比较尾数,且按高位字到低位字的顺序进行比较。设参与比较的2个数为X1和X2,X1相当于被减数,X2相当于减数,比较结果如下: Z=1时,X1=X2。否则,当C=1时,X1>X2;C=0时,X10),或连乘 P1 个二进制浮点数0.1(P1<0),或不用乘(P1=0),就得到二进制浮点数X。为提高转换效率,当 P1 ≥10时,以乘1个二进制浮点数1010(或10-10)代替连乘10个二进制浮点数10(或0.1)。 10 浮点数二翻十子程序BTOD的说明设二进制浮点数为X,若其阶码等于零,直接得到十进制浮点数零。不然,取其数符存于43H单元,为十进制浮点数之数符。并清除42H和40H字节单元,分别作为十进制浮点数之阶符、阶存储单元。通过以下步骤,实现二翻十。 A 测试 X ,若10-10< X <1010,转入B,否则,当 X ≥1010时,使 X ·10-10→ X ,而阶存储单元加10;当 X ≤10-10时,使 X ·1010→ X ,阶存储单元也加10,但置负阶符单元,再转回A继续测试。 B 测试 X ,若10-1< X <10,转入C,否则,当 X ≥10时,使 X ·10-1→ X ,而阶存储单元增1;当 X ≤10时,使 X ·10→ X ,阶存储单元也增1,但置负阶符单元,再转回B继续测试。 C 若 X <1,再做1次 X ·10→ X ,增1阶存储单元,置负阶符单元,此时有1≤ X <10,分离出 X 之整数部分,再将小数部分翻为十进制数,得到十进制浮点数之尾数。尾数小数部分二翻十采用将小数部分乘以100,分离出乘积之整数部,将其翻为2位BCD码的方法。每乘1次100,就分离出2位BCD码。先分离出来的为高位BCD码,如是共分离出8位BCD码,加上整数1位,共9位BCD码。最后,将阶存储单元所存之阶二翻十,得到十进制浮点数之阶。三、 演示程序DMST的说明入口条件:以十进制浮点数作为入口条件,第1操作数(若有)置入30H~37H,共8个字节,其中37H为数符单元;36H为阶符单元,00H为正,0FFH为负;35H为阶单元,2位BCD码;34H~30H为尾数单元,十位BCD码(参看DTOB子程序入口条件),34H为高位字节。若只有1个操作数,则将30H~37H皆清除。第2操作数之入口条件与DTOB子程序相同。演示计算结果占第2操作数之位置。可设断点/准单步运行该程序,以观察计算前浮点数由十进制转化为二进制的情况,二进制浮点数计算结果及转化为十进制浮点数的情况(可与电子计算器相对照)。程序中LCALL FPAD指令可改为LCALL FPSU/FPMU/FPDI/FPDI2/FPSQ及CMPR任意之一(其中CMPR只影响Z、V、C等标志位,可查看PSW验证之)。例:演示浮点数0.1×105开平方。清除2EH字单元,表示正数、正阶。在2DH中置入05(阶)在2C~28H内依次置入10,00,00,00,00,表示尾数为0.1。单步执行演示程序,在执行LCALL DTOB后,可看到0.1×105所对应的二进制浮点数为8E1C400000,8EH为阶码,1C400000H为尾数。执行LCALL FSQR后,看到平方根为8748000000(87H为阶码,48000000H为尾数)。当执行LCALL BTOD之后,得到十进制浮点数位1.0×102,表明10000=100,结果正确无误。MES 注:源程序网上可下载。参考文献 1孙涵芳Intel 16位单片机北京:北京航天航空大学出版社,1995 2涂时亮,姚志石单片机MCS\ 96/98实用子程序.上海:复旦大学出版社,1991 3R 罗德高等数学(第一、二卷)北京:人民教育出版社,1978
标签:
来源:单片机与嵌入式系统应用 作者:珠海志美电子公司 张克彦 时间:2006/2/12 0:00:00