首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

关于分解一个比较大的数为乘积解决方法

2013-01-25 
关于分解一个比较大的数为乘积stm32是16位定时器,也可以级联,但是我要用到5个32位定时器,所以级联不行,于

关于分解一个比较大的数为乘积

stm32是16位定时器,也可以级联,但是我要用到5个32位定时器,所以级联不行,于是设想用动态的预分频扩展为32位,尽量精确,于是设想下面的方法,请各位指教。
   按一分频算出计时cont,
  cont<=0xffff的话,当然就不用分频了。
  cont>0xffff,开方congt ,网上搜出一个开方方法。
static   int   SQRT(int   nRoot)   { 
                int   nSqrt   =   0; 

                for   (int   i   =   0x10000000;   i   !=   0;   i   > > =   2)   { 
                        int   nTemp   =   nSqrt   +   i; 
                        nSqrt   > > =   1; 
                        if   (nTemp   <=   nRoot)   { 
                                nRoot   -=   nTemp; 
                                nSqrt   +=   i; 
                        } 
                } 
                return   nSqrt; 
        } 

速度应该还可以,
    假设得到nSqrt*nSqrt==cont,那么也好办。

   如果不是,   conts=(nSqrt+1)*(nSqrt+1);conts>cont; 
  设      nSqrts=nSqrt+1;

  设想a,  (nSqrts+a)*(nSqrts-a)=cont;
          

     contsa= conts-cont;
    contsa=a*a

    再开方 contsa,得到 a,a不一定是整数,但是取整我认为就是我要的值,误差我就不想分析了, nSqrts-a做预分频, nSqrts+a做计数值,就等到cont了。
  两次开方的运算量。

  但是还有没有比较快的方法,得到一个误差不大的结果,不要求很精确。比如连续除2?

[解决办法]
有误差没关系那就两种办法。第一种牛顿迭代,用f(x)=1/2*(x+n/x)来迭代。算6次就够了。


static int SQRT(int nRoot)
{
  int x = 0xffff;
  for(int i=0;i<6;i++)
    x = (x + nRoot/x) >> 1;
  return x;
}

第二种是二分,直接二分搜索就可以。

牛顿的好处是迭代次数少,但是有除法。二分的好处是没有乘法但是迭代次数多。lz你需要实测才能测出来哪个更快。

热点排行