网站上的二维码,青岛官网seo公司,免费的oa办公系统排名,中国设计之窗官方网站C语言中开平方的算法中要开平方的话,可以在头文件中加#include .然后调sqrt(n);函数即可.但在单片机中要开平方.可以用到下面算法:算法1:本算法只采用移位、加减法、判断和循环实现#xff0c;因为它不需要浮点运算#xff0c;也不需要乘除运算#xff0c;因此可以很方便地运…C语言中开平方的算法中要开平方的话,可以在头文件中加#include .然后调sqrt(n);函数即可.但在单片机中要开平方.可以用到下面算法:算法1:本算法只采用移位、加减法、判断和循环实现因为它不需要浮点运算也不需要乘除运算因此可以很方便地运用到各种芯片上去。我们先来看看10进制下是如何手工计算开方的。先看下面两个算式x 10*p q (1)公式(1)左右平方之后得x^2 100*p^2 20pq q^2 (2)现在假设我们知道x^2和p希望求出q来求出了q也就求出了x^2的开方x了。我们把公式(2)改写为如下格式q (x^2 - 100*p^2)/(20*pq) (3)这个算式左右都有q因此无法直接计算出q来因此手工的开方算法和手工除法算法一样有一步需要猜值。我们来一个手工计算的例子计算1234567890的开方首先我们把这个数两位两位一组分开计算出最高位为3。也就是(3)中的p最下面一行的334为余数也就是公式(3)中的(x^2 - 100*p^2)近似值3 --------------- | 12 34 56 78 90 9 --------------- | 3 34下面我们要找到一个0-9的数q使它最接近满足公式(3)。我们先把p乘以20写在334左边3 q --------------- | 12 34 56 78 90 9 --------------- 6q| 3 34我们看到q为5时(60q*q)的值最接近334而且不超过334。于是我们得到3 5 --------------- | 12 34 56 78 90 9 --------------- 65| 3 34 | 3 25 --------------- 9 56接下来就是重复上面的步骤了这里就不再啰嗦了。这个手工算法其实和10进制关系不大因此我们可以很容易的把它改为二进制改为二进制之后公式(3)就变成了q (x^2 - 4*p^2)/(4*pq) (4)我们来看一个例子计算100(二进制1100100)的开方1 0 1 0 --------------- | 1 10 01 00 1 --------------- 100| 0 10 | 0 00 --------------- | 10 011001| 10 01 --------------- 0 00这里每一步不再是把p乘以20了而是把p乘以4也就是把p右移两位而由于q的值只能为0或者1所以我们只需要判断余数(x^2 - 4*p^2)和(4*p1)的大小关系如果余数大于等于(4*pq)那么该上一个1否则该上一个0。下面给出完成的C语言程序其中root表示prem表示每步计算之后的余数divisor表示(4*p1)通过a30取a的最高 2位通过a2将计算后的最高2位剔除。其中root的两次1相当于4*p。程序完全是按照手工计算改写的应该不难理解。unsigned short sqrt(unsigned long a){unsigned long rem 0;unsigned long root 0;unsigned long divisor 0;for(int i0; i16; i){root 1;rem ((rem 2) (a 30));a 2;divisor (root1) 1;if(divisor rem){rem - divisor;root;}}return (unsigned short)(root);}算法2 :单片机开平方的快速算法因为工作的需要要在单片机上实现开根号的操作。目前开平方的方法大部分是用牛顿迭代法。我在查了一些资料以后找到了一个比牛顿迭代法更加快速的方法。不敢独享介绍给大家希望会有些帮助。1.原理因为排版的原因用pow(X,Y)表示X的Y次幂用B[0]B[1]...B[m-1]表示一个序列其中[x]为下标。假设B[x],b[x]都是二进制序列,取值0或1。M B[m-1]*pow(2,m-1) B[m-2]*pow(2,m-2) ... B[1]*pow(2,1) B[0]*pow(2,0)N b[n-1]*pow(2,n-1) b[n-2]*pow(2,n-2) ... b[1]*pow(2,1) n[0]*pow(2,0)pow(N,2) M(1) N的最高位b[n-1]可以根据M的最高位B[m-1]直接求得。设 m 已知,因为 pow(2, m-1) M pow(2, m)所以 pow(2, (m-1)/2) N pow(2, m/2)如果 m 是奇数设m2*k1,那么 pow(2,k) N pow(2, 1/2k) pow(2, k1),n-1k, nk1(m1)/2如果 m 是偶数设m2k,那么 pow(2,k) N pow(2, k-1/2) pow(2, k-1),n-1k-1,nkm/2所以b[n-1]完全由B[m-1]决定。余数 M[1] M - b[n-1]*pow(2, 2*n-2)(2) N的次高位b[n-2]可以采用试探法来确定。因为b[n-1]1假设b[n-2]1则 pow(b[n-1]*pow(2,n-1) b[n-1]*pow(2,n-2),2) b[n-1]*pow(2,2*n-2) (b[n-1]*pow(2,2*n-2) b[n-2]*pow(2,2*n-4)),然后比较余数M[1]是否大于等于 (pow(2,2)*b[n-1] b[n-2]) * pow(2,2*n-4)。这种比较只须根据B[m-1]、B[m-2]、...、B[2*n-4]便可做出判断其余低位不做比较。若 M[1] (pow(2,2)*b[n-1] b[n-2]) * pow(2,2*n-4), 则假设有效b[n-2] 1余数 M[2] M[1] - pow(pow(2,n-1)*b[n-1] pow(2,n-2)*b[n-2], 2) M[1] -(pow(2,2)1)*pow(2,2*n-4)若 M[1] (pow(2,2)*b[n-1] b[n-2]) * pow(2,2*n-4), 则假设无效b[n-2] 0余数 M[2] M[1]。(3) 同理可以从高位到低位逐位求出M的平方根N的各位。使用这种算法计算32位数的平方根时最多只须比较16次而且每次比较时不必把M的各位逐一比较尤其是开始时比较的位数很少所以消耗的时间远低于牛顿迭代法。2. 实现代码这里给出实现32位无符号整数开方得到16位无符号整数的C语言代码。-------------------------------------------------------------------------------/****************************************//*Function: 开根号处理 *//*入口参数被开方数长整型 *//*出口参数开方结果整型 *//****************************************/unsigned int sqrt_16(unsigned long M){unsigned int N, i;unsigned long tmp, ttp; // 结果、循环计数if (M 0) // 被开方数开方结果也为0return 0;N 0;tmp (M 30); // 获取最高位B[m-1]M 2;if (tmp 1) // 最高位为1{N ; // 结果当前位为1否则为默认的0tmp - N;}for (i15; i0; i--) // 求剩余的15位{N 1; // 左移一位tmp 2;tmp (M 30); // 假设ttp N;ttp (ttp1)1;M 2;if (tmp ttp) // 假设成立{tmp - ttp;N ;}}return N;}以上都是网络查找的资料有些晦涩难懂不过在实际运用中可以使用这些算法。