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