原创 单片机开方算法的实现

2011-2-11 20:04 4563 7 8 分类: MCU/ 嵌入式

以下为快速开放算法的实现,运用在我的实际项目中,我琢磨出来的一种快速开方算法,我项目中使用的是32位数的快速开方算法,并用VB验证过结果,单片机由于资源有限,当实际中遇到16位,8位的开方运算,可以增加速度。如32位开方,只建立2^14的表(根据精度来确定表的大小),16位开方我一般用2^6的表就可以实现,实现的方法就是大数字甩尾,小数字开方保留。

开方快速算法的实现:

为保证计算结果的精度选择方法一。

方法一:在Rom比较充足的情况下做查表,粗算加精算的快速算法做32位数的开方

const unsigned int  sqrt_32[16384]={ 0, 256, 362, 443, 512, 572, 627, 677, 724, 768,。。。。};

建立一个表0~0x3fff数字的开方记做sqrt_32=√a (a=0~0x3fff)*256,扩大256倍,最后一个字节表示小数点后的数,然后根据√b=2n×(√b)/22n,用单片机做就是

long temp0;

unsigned long kaifang(unsigned long ss){

  uint8 dat_count,count;

  long temp1;

  uint8 i;

  i=17;

  dat_count=0;

  temp1=ss>>14;

 

  do{

if((temp1&0x3ffff)!=0x0000){//判断被开方数的最18位是否是1,是1就做右移操作,

//但是必须保证是2的偶数次,当判到有效位小于等于14位的时候进行查表,结束后

//在向右移n位乘回来,可以根据自己要求的精度来建表。

       ss>>=1;

       temp1>>=1;

       dat_count++;

    }

    else {

      if(dat_count%2==0){

       break;

      }

      else{

       ss>>=1;

       dat_count++;

      }

    }

  }while(i-->0);

  temp0=sqrt_32[ss];

  count=dat_count/2;

  for(uint8 j=0;j<count;j++){

    temp0<<=1;

  }

 

  return temp0;

}

该方法在单片机中使用可以大大加快程序的速度,还可以保证在比较高的精度上,缺点太耗rom了。

 

方法2:在程序rom比较小,但是对精度要求不高的场合可以使用

unsigned int sqrt_16(unsigned long dat){

     unsigned int NN, i;

     unsigned long tmp, ttp;    // 结果、循环计数

     if (dat == 0)                // 被开方数,开方结果也为0

         return 0;

     NN = 0;

     tmp = (dat >> 30);           // 获取最高位:B[m-1]

     dat <<= 2;

     if (tmp > 1) {              // 最高位为1

         NN ++;                  // 结果当前位为1,否则为默认的0

         tmp -= NN;

     }

     for (i=15; i>0; i--) {      // 求剩余的15位

         NN <<= 1;               // 左移一位

         tmp <<= 2;

         tmp += (dat >> 30);      // 假设

         ttp = NN;

         ttp = (ttp<<1)+1;

         dat <<= 2;

//////////////////////////////////版权所有,如需转载注明出处 鱼香茄子/////////////////////////////////////////////

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户403143 2011-2-11 19:59

改天我用ARM测一下。 感谢
相关推荐阅读
用户1664151 2013-07-01 16:10
[博客大赛]对K60低频时钟的看法
         最近项目中使用FREESCALE,K60的芯片,在小批量试产的时候出现了部分晶振不能起振的情况,搞了几天,一直没有搞定,怀疑过晶振品质的问题,后来查阅低频32768Hz的晶振为西...
用户1664151 2013-06-29 14:26
我回来了
        很久没来EDN,工作一直比较忙碌,现在我又回来了,几多沉下浮,曾经犹豫彷徨是技术还是非技术,现在看来技术还是比较适合我的。          适合自己的才是最好的,EDN CH...
用户1664151 2011-08-24 22:43
蜗牛学习lwip
开始学习LWIP,手头的9b96要开始发挥作用了,对CM3不是很熟,但是一步一步来爬着学习,打算弄明白LWIP的代码,TCPIP是在是太庞大了,学通这个东西真会变的很好很强大,记录每天学习的过程。。加...
用户1664151 2011-05-25 20:57
浅谈零磁通补偿技术
    最近一直在整这个玩意,思考和实践做好一个东西真的太不容易,我最近一直在研究在小电流条件下的隔离测量技术,对于几百Ua的信号高保真的还原,我是下了苦工的,现在只是浅浅的踏进了这扇门,我使用POM...
用户1664151 2011-05-19 21:20
sim300之短信包Bit7编码解析
上回讲解sim300的GPRS建立过程,这回讲解sim300的短信包Bit7编码解析,使用这样的方式的时候只支持英文和数据短信,可以让模块具有短信设置功能的能力。一下是解析过程的代码。 //bit7转...
用户1664151 2011-05-19 21:12
lm3s8962开发板学习之电平中断
attachment download今天学习开发板上点平中断的,程序在LCD上显示按的5个按键的信息。与君分享。...
EE直播间
更多
我要评论
1
7
关闭 站长推荐上一条 /3 下一条