单片机浮点数运算之比较
- 格式:doc
- 大小:31.00 KB
- 文档页数:2
单⽚机浮点数计算在单⽚机应⽤系统的数据处理过程中,经常会遇到⼩数的运算问题,如求解BCD的增量算式、线性化处理等。
因此,需要⽤⼆进制数来表⽰⼩数。
表⽰⼩数的⽅法⼀般有两种,定点数和浮点数。
定点数结构简单,与整数的运算过程相同,运算速度快。
但随着所表⽰数的范围的扩⼤,其位数成倍增加,给运算和存储带来不便,⽽且也不能保证相对精度不变。
浮点数的结构相对复杂,但它能够以固定的字节长度保持相对精度不变,⽤较少的字节表⽰很⼤的数的范围,便于存储和运算,在处理的数据范围较⼤和要求精度较⾼时,采⽤浮点数。
浮点数的概念常⽤的科学计数法来表⽰⼀个⼗进制数如l234.75=1.23475E3=1.23475×103在数据很⼤或很⼩时,采⽤科学计数避免了在有效数字前加0来确定⼩数点的位置,突出了数据的有效数字的位数,简化了数据的表⽰。
可以认为,科学计数法就是⼗进制数的浮点数表⽰⽅法。
在⼆进制效中,也可以⽤类似的⽅法来表⽰⼀个数,如1234.75=0.11(⼆进制)=0.1×211⼀般表达式为N=S×2p在这种表⽰⽅法中,数值由四个部分组成,即尾数S及符号,阶码P及符号。
在⼆进制中,通过定义相应字节或位来表⽰这四部分,就形成了⼆进制浮点数。
⼆进制浮点数可以有多种不同的表⽰⽅法,下⾯是⼀种常见的三字节浮点数的格式:其中尾数占16位,阶码占6位,阶符占1位,数符占1位。
阶码通常⽤补码来表⽰。
在这种表⽰⽅法中,⼩数点的实际位置要由阶码来确定,⽽阶码⼜是可变的,因此称为浮点数。
1234.75⽤这种格式的浮点数表⽰就是:00 1011 1001 10 01 1000⽤⼗六进制表⽰为1234.75=0B9A58H-1234.75=4B9A58H0.171875=043B00H-0.171875=443B00H三字节浮点数所能表⽰的最⼤值为1×263=9.22×1018能表⽰的最⼩数的绝对值为0.5×2-63=5.42×10-20其所表⽰的数的绝对值范围=(5.42×10-20~9.22×1018),由此可以看到,⽐三字节定点数表⽰的数的范围⼤得多。
串口通信中整型和浮点型数据的处理和发送在做下位机通信时往往会用到串口,包括下位机将数据传输给上位机,或者是下位机与下位机之间进行数据传输,这时候就会遇到发送数据的问题,单片机通过串口发送数据时往往是一次一个字节(8位),如果传输char(8位)型数据则很好办,只需要直接发送就可以了,但是在发送int型数据和float型数据时就会稍微有些复杂。
下面就以常用的8位单片机89c51为例来进行说明。
当发送int型或long型数据时还比较简单,一个int型数据是16位,long是32位,把int型/long型数据变成2/4个char型数据发送出去就可以了,程序如下void long_char(unsigned long l,unsigned char *s){*s = l>>24;*(s+1) = l>>16;*(s+2) = l>>8;*(s+3) = l;}在串口助手上就可以接收到相应的long型数据了。
当发送float型数据时稍微有些复杂。
下面简单介绍下float型数据在内存中的存储方式(double类似,以下部分参考了别人的博客)。
float遵从的是IEEE R32.24 在存储中都分为三个部分:1.符号位(Sign) : 0代表正,1代表为负2.指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储3.尾数部分(Mantissa):尾数部分float的存储方式如下图所示:R32.24和R64.53的存储方式都是用科学计数法来存储数据的,比如8.25用十进制的科学计数法表示就为:8.25*,而120.5可以表示为:1.205*而计算机根本不认识十进制的数据,他只认识0,1,所以在计算机存储中,首先要将上面的数更改为二进制的科学计数法表示,8.25用二进制表示可表示为1000.01,120.5用二进制表示为:1110110.1。
用二进制的科学计数法表示1000.01可以表示为1.00001*,1110110.1可以表示为1.1101101*,任何一个数都的科学计数法表示都为1.xxx*, 尾数部分就可以表示为xxxx,第一位都是1,所以可以将小数点前面的1省略,所以23bit的尾数部分,可以表示的精度却变成了24bit,道理就是在这里,那24bit能精确到小数点后几位呢,我们知道9的二进制表示为1001,所以4bit能精确十进制中的1位小数点,24bit就能使float能精确到小数点后6位,而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了,所以指数部分的存储采用移位存储,存储的数据为元数据127,下面就看看8.25和120.5在内存中真正的存储方式。
51单片机小数运算
51单片机是一种常用的微控制器芯片,可以实现各种数值计算操作。
其中,小数运算是比较常见的一种操作。
在本篇文章中,我们将介绍51单片机的小数运算原理及其实现方法。
首先,我们需要了解51单片机的数值表示方法。
51单片机一般采用定点数表示法,即用二进制数表示实际数值的定点数值。
在定点数表示法中,一个数值被分为整数部分和小数部分,其中小数部分的位数是固定的。
例如,若小数部分的位数为8位,那么一个数值的取值范围为0~255,可以表示0~1之间的任意实数。
在实现小数运算时,我们可以采用以下两种方法:
1. 将小数转换为整数进行运算
这种方法比较简单,可以采用将小数扩大一定倍数的方式将其转换为整数。
例如,若我们将小数扩大100倍,那么0.123就可以转换为12。
然后,我们可以使用51单片机的整数运算指令进行运算。
完成运算后,再将结果除以扩大的倍数即可得到正确的小数结果。
2. 使用浮点数算法
这种方法可以直接对小数进行运算,不需要进行转换。
但是,51单片机并不支持浮点数运算指令,我们需要通过软件仿真的方式实现浮点数运算。
具体实现方法可以参考相关的软件仿真文档或者使用第三方的库函数来实现。
综上所述,51单片机的小数运算可以通过将小数转换为整数进行运算或者使用浮点数算法来实现。
在实际应用中,我们可以根据需
要选择适合的方法来实现小数运算。
利用单片机进行复杂函数计算的一种高精度算法作者:逯伟来源:《现代电子技术》2013年第17期摘要:单片机在移动设备中的应用越来越广泛,要求单片机具备的数据处理能力越来越强。
但单片机的资源有限,如何让其能够解算复杂函数变得非常具有实际意义,也成为困扰许多专家的难题之一。
介绍了一种在汇编环境下如何利用插值法与查表法相结合进行复杂三角函数运算的方法。
利用这种算法可使三角函数的解算精度达到0.000 1,存储空间减小了97%,对有关内容进行了比较全面的阐述。
此方法计算精度高、应用范围广、易掌握。
关键词:单片机;复杂函数计算;插值法;查表法中图分类号: TN710⁃34 文献标识码: A 文章编号: 1004⁃373X(2013)17⁃0163⁃020 引言在各种测量及控制中,通常都要求仪器体积小、便携,所以单片机在测量仪器中的应用日益广泛。
现代工业仪器智能化要求越来越高,对复杂三角函数的计算量越来越大,以目前单片机所具有的资源和技术能力,要想达到上述要求,对技术人员的编程技巧要求是非常高的,工作量也非常庞大。
基于以上原因,目前特别需要研究出一种对单片机资源要求低,易编程,又能保证很高计算精度要求的算法。
1 单片机处理数据的常见方法单片机处理数据的方法有两种:浮点数和定点数。
浮点数数据运算在汇编环境下编程复杂、运算量大,对内存容量要求高,且对单片机的运算速度有很高要求,这样普通51系列单片机无法满足复杂函数的计算。
定点数在数据运算中运算量较小,编程简单,速度快,但是精度低,如何做到既不降低计算精度又能保证数据处理速度,成为复杂函数在51单片机使用技术中的一个难点。
2 基本原理求解三角函数采用的是综合运用数学中的插值法和查表法。
单纯使用查表法求解三角函数值时,如果把0~90°每隔0.01°的函数值都存储在列表中,需要存9 000个函数值,一个函数值占两个字节,9 000个函数值就是18 000 B,如果精度要求更高所需的字节更大,程序非常庞大,还要占用很大的内存空间,一般51系列单片机的内存已不能满足要求,必须进行存储器扩展,这样势必加大成本,增大体积和功耗。
单片机浮点数的实用快速除法介绍
作为单片机程序员来说,在编写程序时经常要检验程序中的浮点数运算
结果是否正确,但手中又没有合适的检验工具,非常麻烦。
而一般单片机是没
有浮点数运算指令的,必须自行编制相应软件。
在进行除法计算时,通常使用
的方法是比较除法,即利用循环移位和减法操作来得到24~32 位商,效率很低。
这里给出一种浮点数除法运算的实用快速算法。
该方法以数值计算中的预
估-修正方法为指导,充分利用了16 位单片机的乘除法功能,很轻易地实现了
浮点数的除法。
1 浮点数格式
IEEE 的浮点数标准规定了单精度(4 字节)、双精度(8 字节)和扩展精度(10 字节)三种浮点数的格式。
最常用的是单精度浮点数,格式如图1 所示。
但是这种格式的阶码不在同一个字节单元内,不易寻址,从而会影响运算速度。
通常在单片机上采用的是一种变形格式的浮点数,如图2 所示。
其中的23 位尾数加上隐含的最高位1,构成一个定点原码小数,即尾数为小于1 大于
等于0.5 的小数。
2 快速除法的算法原理
在16 位单片机中只有16 位的乘除法,而浮点数的精度(即尾数的有效
位数)达24 位,因此无法直接相除,但依然可以利用16 位的乘除法指令来实
现24 位除法。
不过,如果只进行一次16 位的除法必定会带来很大误差,因此
问题的关键在于如何消除这个误差,从而达到要求的精度。
这其实就是通常数。
arm 浮点数的比较汇编指令ARM浮点数比较汇编指令,在ARM体系结构中,主要有三种浮点数比较指令:FCCMPE(float compare compare NaN and set EFLAGS)、FCMPE(float compare setting EFLAGS)和FCMP(float compare 比较两个单精度的浮点数,并设置条件标志位)。
下面我们一步步来了解这三种浮点数比较指令:1. FCCMPE指令FCCMPE指令进行的是浮点数比较操作,并且会比较NaN(非数字),最后会将标志位设置为0或1。
使用FCCMPE指令的语法如下:FCCMPE Dn, Dm其中,Dn和Dm是两个浮点寄存器,用于比较操作。
指令执行后,标志位将被设置为0或1。
如果Dn和Dm中的一个是NaN,那么标志位将被设置为1,否则为0。
2. FCMPE指令FCMPE指令执行浮点数比较操作,并将比较结果存储在条件码寄存器中。
使用FCMPE指令的语法如下:FCMPE Dn, Dm其中,Dn和Dm是两个浮点寄存器,用于比较操作。
指令执行后,条件码寄存器中的标志位将被设置为:* Z(位0):结果为零时设置为1。
* N(位1):结果为负数时设置为1。
* C(位2):无符号数操作中,表示结果比较时进位或借位。
在有符号数操作中,表示结果的最高位(符号位)。
3. FCMP指令FCMP指令比较两个单精度的浮点数,并设置条件标志位。
使用FCMP指令的语法如下:FCMP Dn, Dm其中,Dn和Dm是两个浮点寄存器,用于比较操作。
指令执行后,条件码寄存器中的标志位将被设置为:* Z(位0):结果为零时设置为1。
* N(位1):结果为负数时设置为1。
* C(位2):无符号数操作中,表示结果比较时进位或借位。
在有符号数操作中,表示结果的最高位(符号位)。
综上所述,ARM浮点数比较汇编指令主要有三种:FCCMPE、FCMPE 和FCMP。
它们在比较操作时的表现略有不同,但最终都会将比较结果存储在标志位或条件码寄存器中,方便程序对比较结果进行判断和处理。
基于单片机的反时限过流保护算法摘要:反时限保护是指动作时间与故障电流成反比,此种关系一般使用反时限曲线来表示。
而反时限保护的实现一般可以使用查表,曲线拟合,自适应神经元与公式计算等方法。
而这些计算中有些使用浮点运算,所以在实际实现中需要进行简化,简化时会带来相应误差。
本文主要对复杂的反时限方程的各种实现方法进行分析并计算相应误差,以方便针对不同单片机选择使用的反时限计算方法。
关键词:反时限;查表法;曲线拟合;单片机;误差分析;0.引言反时限保护指的是故障电流与动作时间成反比,即故障电流越大,动作时间越短。
反时限保护特性一般使用反时限曲线表示,即用一个方程式表示故障电流与动作时间的关系,此方程式反应的曲线即为反时限曲线。
此方程式基于如下数学模型:Nα×t = K(1)其中t表示动作时间,K为反时限常数,K可以表示为β×Tr,其中β为工厂设定常数,Tr为用户设定时间;N为动作电流与设定电流比一般使用I/Ir表示,I表示动作电流,Ir表示长延时设定值;α表示电流指数,表示在同样常数下相应曲线的速率。
IEC 60255-3 推荐了一个反时限数学模型:,(2)其中 1为曲线移动常数,表示电流比为1时,动作时间无穷大,即不动作。
在较为通用的模型中1可以根据需要使用一个常数代替。
一般提供反延时保护的产品核心都是使用单片机,可能根据产品的实际需求使用8位,16位或32位单片机。
对公式2中的α,国际相关标准规定了几种值,对于有些值,单片机比较容易实现,而有些值,单片机可能实现比较困难。
而以前相关文献只是对其中一部分曲线进行分析,并且算法中一般采用浮点数表示,此表示方法在单片机中比较难以实现。
本文对其中多个复杂曲线进行算法分析,并进行一定的简化,以方便单片机实现。
1.反时限保护的算法分析1.1 反时限保护特征曲线IEC-255-4对公式2进行了具体定义,有以下三种曲线:一般反时限,(3)非常反时限,(4)特别反时限,(5)公式中0.14,13,5,80即公式2中的β,用户可以根据需要进行计算得到自己需要的常数,如常用规定6倍设定时间的动作时间,可以根据此时间算出相应的β。
⼀篇⽂章带你了解C语⾔浮点数之间的⽐较规则⽬录你认为这段代码输出什么?为什么不等于呢?应该怎么解决?那么怎么判断两个浮点数 f1 和 f2 相等呢。
伪代码可以简化为 >>怎么判断浮点数等于0?还有⼀个问题总结你认为这段代码输出什么?int main(){float f1 = 1.1;float f2 = 2.2;if (f2 - 1.1 == f1)printf("等于");elseprintf("不等于");return 0;}答案是不等于。
为什么不等于呢?因为在C语⾔中浮点数是存在精度损失的,有可能⽐原来的数⼤,也有可能⼩。
在下图所⽰,f1在打印⼩数点后30位时就能很明显的看出存在精度损失。
应该怎么解决?浮点数不能直接⽤ == 号⽐较。
那么应该怎么⽐较呢。
这⾥要引出精度这个概念,精度可以理解为引发⼀个浮点数发⽣改变的最⼩值。
当⼀个浮点数加上精度或者减去精度,都不等于该数本⾝。
精度可以是⾃⼰定义的,也可以⽤C语⾔⾃带的,它定义在 float.h 头⽂件中。
#define FLT_EPSILON 1.192092896e-07F // smallest such that 1.0+FLT_EPSILON != 1.0#define DBL_EPSILON 2.2204460492503131e-016 // smallest such that 1.0+DBL_EPSILON != 1.0FLT_EPSILON 为float类型的默认精度,DBL_EPSILON 为double类型的精度。
那么怎么判断两个浮点数 f1 和 f2 相等呢。
虽然两个浮点数存在精度上的误差,但这个误差⾮常⼩,只要(f2 - f1)这个差值在负精度到正精度的区间内,就可以认为它们相等。
如图,它们的差值必须在 (-XXX_EPSILON,XXX_EPSILON) 这个区间内,才能说明它们相等。
浮点数比较问题1、直接进行关系比较的错误(==)浮点数可以进行比较,但是由于不同浮点类型中表示精度的差异,所以会引起一些错误。
例1 :#include <iostream.h>void main(){float f1=7.123456789;float f2=7.123456787;cout<<(f1!=f2?”not same\n”:”same\n”);float g=1.0/3.0;double d=1.0/3.0;cout<<(g = =d?”same\n”:”not same\n”);}运行结果:same //f1与f2相同not same //g与d不同f1与f2的前6位有效数位相等而后面的数不同,在计算机中可能被表示为同一个数。
因float型精度有限,不能分辨其差异,造成判断有误(认为是相同的数)。
解决的方法是使用double型数据。
例2:#include <iostream.h>#include <math.h>#include <iomanip.h>void main(){double d1=123456789.9*9;double d2=1111111109.1;cout<<(d1==d2?" same\n":"not same\n");cout<< ((fabs(d1-d2)<1e-6)?"same\n":"not same\n");cout<<setprecision(9);cout<<setiosflags(ios::fixed)<<d1<<"\n"<<d2<<"\n";}运行结果:not samesame1111111109.1000001431111111109.0999999052、使用浮点数进行相等(==)和不相等(!=)比较的操作通常是有问题的。
单片机浮点数运算之比较
今天心血来潮,做了几种单片机之间浮点数运算速度的比较,实验很简单,编一个实现两个浮点数相乘的小程序,然后编译、仿真,看看每种单片机执行乘法运算需要多少个机器周期,程序如下:
void main(void)
{
float i,j;
i=12.8;
j=3.1415926;
i=i*j;
for(;i>0;i--); //避免编译警告或被优化掉
while(1);
}
进行比较实验的单片机及相关数据如下(以下执行时间均是指执行i=i*j所用指令周周期):AVR:
实验芯片型号:ATMAGE16
编译仿真环境:IAR FOR AVR5.30
执行时间:181
MSP430:
实验芯:MSP430F2132
编译仿真环境:IAR FOR MSP230 5.10
执行时间:326
STM32:
实验芯:STM32F107xC
编译仿真环境:IAR FOR ARM 5.41
执行时间:38
PIC16单片机:
实验芯片:PIC16F877A
编译仿真环境:MPLAB 8.53 + PICC9.70
执行时间:1314
51单片机:
实验芯片:AT89C51
编译仿真环境:Keil uVision2
执行时间:207
执行时间(指令周期)比较图
从结果可以看出,执行效率最高、速度最快的当属smt32。
当然,stm32与其它另外4种单片机不是一个等级的。
效率最低、速度最慢的就是PIC了,如果采用同样的晶振频率,PIC的执行时间将是AVR 的28倍!做为16位单片机的MSP430让人有点小失望,竟然还干不过51,如果换用单周期的51单片机,那么它的执行速度也只略逊于AVR.
总结:
AVR不愧于“高速单片机”的称号;
MSP430优势有在速度上,在于它的低功耗设计;
PIC指令效率太低
51不愧是最经典的单片机;
Stm32不是神话,只因为它是ARM Cortex-M3。