资源描述:
《单片机C语言求平方根函数.doc》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、个人收集整理-ZQ单片机C语言求平方根函数转自:在单片机中要开平方.可以用到下面算法: 算法: 本算法只采用移位、加减法、判断和循环实现,因为它不需要浮点运算,也不需要乘除运算,因此可以很方便地运用到各种芯片上去。我们先来看看进制下是如何手工计算开方的。先看下面两个算式,* ()公式()左右平方之后得:^*^^()现在假设我们知道^和,希望求出来,求出了也就求出了^的开方了。我们把公式()改写为如下格式:(^*^)(*)()这个算式左右都有,因此无法直接计算出来,因此手工的开方算法和手工除法算法一样有一步需要
2、猜值。我们来一个手工计算的例子:计算的开方首先我们把这个数两位两位一组分开,计算出最高位为。也就是()中的,最下面一行的为余数,也就是公式()中的(^*^)近似值 下面我们要找到一个的数使它最接近满足公式()。我们先把乘以写在左边: 我们看到为时(*)的值最接近,而且不超过。于是我们得到: 接下来就是重复上
3、面的步骤了,这里就不再啰嗦了。 4/4个人收集整理-ZQ这个手工算法其实和进制关系不大,因此我们可以很容易的把它改为二进制,改为二进制之后,公式()就变成了:(^*^)(*)()我们来看一个例子,计算(二进制)的开方: 这里每一步不再是把乘以了,而是把乘以,也就是把右移两位,而由于的值只能为或者,所以我们只需要判断余数(^*^)和(*)的大小关系,如果余数大于等于(*)那么该上一个,否则该上一个。下
4、面给出完成的语言程序,其中表示,表示每步计算之后的余数,表示(*),通过>>取的最高位,通过<<将计算后的最高位剔除。其中的两次<<相当于*。程序完全是按照手工计算改写的,应该不难理解。(){ ; ; ; (;<;){ <<; ((<<)(>>)); <<; (<<); (<){ ; ; } } ()();} 算法:单片机开平方的快速算法因为工作的需要,要在单片机上实现开根号的操作。目前开平方的方法大部分是用牛顿迭代法。我在查了一些资料以后找到了一个比牛顿迭代
5、法更加快速的方法。不敢独享,介绍给大家,希望会有些帮助。.原理因为排版的原因,用()表示的次幂,用[],[],...,[]表示一个序列,其中[]为下标。假设: [][]都是二进制序列,取值或。 []*()[]*()...[]*()[]*() []*()[]*()...[]*()[]*() ()4/4个人收集整理-ZQ ()的最高位[]可以根据的最高位[]直接求得。 设已知,因为(,)<<(,),所以(,())<<(,) 如果是奇数,设*, 那么()<<(,)<(,), ,() 如果是偶数,
6、设, 那么()>>(,)>(,), 所以[]完全由[]决定。 余数[][]*(,*) ()的次高位[]可以采用试探法来确定。 因为[],假设[],则([]*()[]*(),)[]*(*)([]*(*)[]*(*)), 然后比较余数[]是否大于等于(()*[][])*(*)。这种比较只须根据[]、[]、...、[*]便可做出判断,其余低位不做比较。 若[]>(()*[][])*(*),则假设有效,[]; 余数[][](()*[]()*[],)[](())*(*); 若[]<(()*[][]
7、)*(*),则假设无效,[];余数[][]。 ()同理,可以从高位到低位逐位求出的平方根的各位。使用这种算法计算位数的平方根时最多只须比较次,而且每次比较时不必把的各位逐一比较,尤其是开始时比较的位数很少,所以消耗的时间远低于牛顿迭代法。.实现代码这里给出实现位无符号整数开方得到位无符号整数的语言代码。4/4个人收集整理-ZQ*****************************************:开根号处理 **入口参数:被开方数,长整型 **出口参数:开方
8、结果,整型 *****************************************(){ ,; ,; 结果、循环计数 () 被开方数,开方结果也为 ; ;