单片机浮点数的实用快速降法

发布者:eta17最新更新时间:2012-03-08 来源: 21IC 关键字:浮点数  尾数  快速降法 手机看文章 扫描二维码
随时随地手机看文章

在较为复杂的单片机系统中,为扩大取值范围,实现复杂的计算和控制,一般都要涉及浮点数的运算。而一般单片机是没有浮点数运算指令的,必须自行编制相应软件。在进行除法计算时,通常使用的方法是比较除法[1],即利用循环移位和减法操作来得到24~32 位商,效率很低。有些文献给出了一些改进方法[2],但思想不清晰,很难推广使用。这里给出一种浮点数除法运算的实用快速算法。该方法以数值计算中的预估 -修正方法为指导,充分利用了16位单片机的乘除法功能,很轻易地实现了浮点数的除法。

1 浮点数格式

IEEE的浮点数标准规定了单精度(4字节)、双精度(8字节)和扩展精度(10字节)三种浮点数的格式。最常用的是单精度浮点数,格式如图1所示。但是这种格式的阶码不在同一个字节单元内,不易寻址,从而会影响运算速度。

通常在单片机上采用的是一种变形格式的浮点数,如图2所示。其中的23位尾数加上隐含的最高位1,构成一个定点原码小数,即尾数为小于1大于等于0.5的小数。有关浮点数格式的详细内容请参考有关文献[1][2]。

2 快速除法的算法原理

在16 位单片机中只有16位的乘除法,而浮点数的精度(即尾数的有效位数)达24位,因此无法直接相除,但依然可以利用16位的乘除法指令来实现24位除法。不过,如果只进行一次16位的除法必定会带来很大误差,因此问题的关键在于如何消除这个误差,从而达到要求的精度。这其实就是通常数值计算中所采用的预估- 修正方法。

假设两个浮点数经过预处理后,被除数和除数尾数扩展为32位(末8位为0)分别放入X和Y中。邻YL为Y的低16位,并记YH=Y-YL。显然YH≈Y,X/Y与Y/YH相差不多:

(X/Y)/(X/YH)=(YH/Y)

=YH/(YH+YL)

=1/(1+YL/YH)

≈1-YL/YH

=(YH-YL)/YL[page]

可见只需要在X/YH的基础上再乘以一个修正因子(YH-YL)/YH,就可以得到X/Y的一次校准值。不难证明这个值已经达到了24位的精度要求。事实上,相对误差满足:


    这说明这个一次校准值完全可以作为最终的结果。

3 算法的具体实现

在具体实现本算法时,主要经过下列步骤:

(1)计算预估值Q0=X/YH;

(2)计算修正因子Q1=(YH-YL)/YH;

(3)计算校准值Q=Q0×Q1,并作为最后结果。

这里的YH虽仍是32位,但其低16位已为0,计算时可以将它视为16位数,这不会影响计算精度。通过两次16位除法,就可得到精确的32位结果。例如,计算Q0时,第一次除法,X除以YH的高16位,得到的商为Q0的高16位,而16位余数末尾添0成 32位,再除以YH的高16位,得到Q0的低16位(余数舍去)。由此得到了32位的Q0。

在具体运算中,X应选除以4(X左移2位),以保证Q0不会溢出(YH取高16位):

Q0'=(Y/4)/YH≤(0ffffff00H/4)/8000H=7fffh

由于X为32位(末8位为0),这一操作不影响有效数字。而Q1(YH-YL)/YH≤1,不存在溢出的问题。最后计算校准值Q时,有Q=4Q0'Q1。

在计算Q0'、Q1时,均进行了两次16位除法,使得Q0'、Q1均为精确的32位,保证了计算过程中的精度,减小了累积误差。对于YL=0即除数只有16位有效数字的特殊情况,直接有Q1=1,还能省去两次16位除法。

在计算Q时,则通过3次16位乘法实现了32位乘法,取结果的高32位,即得Q。

整个算法至多只须用4次除法、3次乘法和5次加法,就求得了浮点数商的尾数,可见计算效率是很高的,保证了运算速度。

浮点数除法流程图如图3所示。

 

[page]

 

4 程序源代码

限于篇幅,只给出源代码中的关键部分,即有效数字的计算部分。

;被除数为x,除数为y

;用yh,hl分别表示y的高16位和低16位

...

;假设x,y的有效数字部分分别在(dx,cx)和(bx,ax)中

;计算预估值Q0'=(x/4)/yh

shrl cx,#2 ;计算x/4

divu cx,bx ;计算(x/4)÷yh

ld fx, cx ;把商暂放入寄存器fx,即Q0'的高16位有 ;效数字

clr cx

divu cx,bx ;把余数末尾添0后面再除以yh

ld ex,cx ;把商暂放入寄存器ex,即Q0'

;的低16位有效数字

;(fx,ex)=Q0'

;计算修正因子 Q1=(yh-yl)/yh

cmp ax,0 ;判断yl是否为0

jne getQ1 ;若yl非0,计算修正因数Q1

ld ax,ex ;若yl=0,修正因数Q1=1

ld bx,fx ;(Q0'×Q1)=Q0',可以直接计算Q

sjmp getQ

getQ1:

ld hx,bx ;把yh放于寄存器hx中

neg ax

dec bx ;计算yh-yl

divu ax,hx ;计算Q1=(yh-yl)÷yh

ld dx,ax ;把商暂时放入寄存器dx,即Q1的高16位有;效数字

clr ax

divu ax,hx ;把余数末尾添0后再除以yh,得Q1的;低16位有效数字

ld bx dx ;(bx,ax)=Q1

;计算Q0'×Q1=(fx,ex)×(bx,ax),只取32位有效数字

ld hx,bx

mulu cx,bx,ex ;(dx,cx)=bx×ex

mulu ax,fx ;(bx,ax)=ax×fx

clr ex

add cx,ax

addc dx,bx

addc ex,0 ;(ex,dx,cx)=(dx,cx)+(bx,ax)

mulu ax,fx,hx ;(bx,ax)=fx×hx

add ax,dx ;(bx,ax)=(bx,ax)+(ex,dx)

addc bx,ex ;(bx,ax)=Q0'×Q1

;计算校准值Q=(Q0' ×Q1)×4并调整阶码

getQ:

...

代码到这里为止,浮点数商的有效数字已经全部求出。只要再执行一些调整浮点数阶码的操作,就可以得到最终结果。

在作者开发的一个80C196KC单片机系统中,涉及到了二进制-十进制数制转换、分段线性插值、数字滤波等大量浮点数的运算,都是靠加减乘除等底层函数来实现的。

此外,本算法思路清晰,因此很容易加以推广。例如,为了得到更高的精度,可取修正因子:

则相对误差,转化为十进制,有效数字高达14位。
关键字:浮点数  尾数  快速降法 引用地址:单片机浮点数的实用快速降法

上一篇:用AT90S1200代换显示驱动芯片MC14499的应用电路
下一篇:用单片机实现可编程逻辑器件的配置

推荐阅读最新更新时间:2024-03-16 12:54

ARM下浮点数Middle-Endian问题的处理
摘要:本文描述了嵌入式GIS软件从X86平台移植到ARM体系结构平台的过程中遇到的浮点数存储字节顺序问题,并对该问题进行了详细分析,最终确定是ARM体系结构下浮点数的Middle-Endian存储问题,并提供了解决方案。   随着嵌入式微处理器芯片性能的日益提高,嵌入式设备也得到了广泛的应用。随着应用的扩展,嵌入式软件的开发也呈现出功能多样化、平台多样化和体系结构多样化等特点。   由于可移植性好,相当一部分嵌入式软件都是用C/C++语言开发的,而C/C++语言编写的程序中数据存储字节顺序是与编译平台所用的CPU相关的,所以嵌入式软件移植过程中,数据存储字节顺序是需要重点处理的地方。   在嵌入式GIS软件从X86体系结构下
[模拟电子]
STM32 无法通过 %f 打印浮点数
一、问题 使用 IAR 开发 STM32,发现无法通过 printf 重定向到串口打印出浮点数。代码如下: 输出结果如下: 可见,浮点数部分无法正常显示。 二、解决方法 这是由于 IAR 默认选择的 printf 库不支持浮点数的的输出。可在设置选项中修改。如下:默认使用 small,改为 auto 即可。 三、备注 在不修改设置的情况下,尝试过如下两种代码解决。一种是通过 sprintf 将浮点数转换成字符串输出,另一种是分解整数和小数部分,分别输出。第一种方法也是不可行的,只有分解可以。 代码如下: /* * cyang 2018/2/27 * mcu printf float value */ #in
[单片机]
ARM体系下浮点数Middle-Endian问题的处理
  随着嵌入式微处理器芯片性能的日益提高,嵌入式设备也得到了广泛的应用。随着应用的扩展,嵌入式软件开发也呈现出功能多样化、平台多样化、体系结构多样化的特点。   由于可移植性好,相当一部分嵌入式软件都是用C/C++语言开发的,而C/C++语言编写的程序中数据存储字节顺序是与编译平台所用的CPU相关的,所以嵌入式软件移植过程中,数据存储字节顺序是需要重点处理的地方。   在嵌入式GIS软件从x86体系结构下移植到ARM体系结构的过程中,遇到了浮点数据存储字节顺序的问题。该问题既不是Big-Endian,也不是Little-Endian,而是Middle-Endian字节顺序。本文先介绍该嵌入式GIS软件开发平台和运行平台,再
[单片机]
ARM体系下<font color='red'>浮点数</font>Middle-Endian问题的处理
浮点数转换成字符串函数
sprintf函数太大,在STM8上面根本不敢用,动不动就.text overflow。为了将采集的数值通过串口上传到计算机,只能自己写了一个浮点数转换成字符串的函数: #include stdio.h #include stdint.h static char table ={'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; void num2char(char *str, double number, u
[单片机]
ST新款 STM32F3浮点数字信号控制器面市
中国,2014年4月29日 ——意法半导体宣布其新款的STM32F301/302/303系列微控制器已经量产,并可通过经销渠道订货。基于集成浮点单元(FPU)的ARM®Cortex®-M4内核,新产品具有出色的处理性能和系统芯片的集成度,针对注重价值的先进应用。 作为市场上首个低于1美元并实现量产、集成FPU的Cortex-M4微控制器, 新的STM32F301基本型微控制器集成32KB-64KB片上闪存和16KB SRAM,让客户轻松迈入ARM®Cortex®-M4微控制器应用开发行列。STM32F302和STM32F303将闪存容量从32KB拓展至256KB。年底,意法半导体还将推出闪存容量高达512KB的STM
[嵌入式]
ST新款 STM32F3<font color='red'>浮点数</font>字信号控制器面市
LCD浮点数显示函数的探讨
单片机开放附赠的学习资料里面很少见到显示浮点数的函数,显示浮点数的操作也相当烦坠! 一般转换显示法 拿STM32单片机资源,我们选取ADC采样部分函数来看显示过程 adcx=Get_Adc_Average(ADC_Channel_5,20); LCD_ShowxNum(134,130,adcx,4,16,0); temp=(float)adcx*(3.3/4096); adcx=temp; LCD_ShowxNum(134,150,adcx,1,16,0); temp-=adcx; temp*=1000; LCD_ShowxN
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved