读书人

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

发布时间: 2013-01-25 15:55:29 作者: rapoo

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

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你需要实测才能测出来哪个更快。

读书人网 >软件架构设计

热点推荐