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*p+q) (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时(60+q*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*p+q) (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*p+1)的大小关系,如果余数大于等于(4*p+q)那么该上一个1,否则该上一个0。

下面给出完成的C语言程序,其中root表示p,rem表示每步计算之后的余数,divisor表示(4*p+1),通过a>>30取a的最高 2位,通过a<<=2将计算后的最高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 i=0; i<16; i++){

root <<= 1;

rem = ((rem << 2) + (a >> 30));

a <<= 2;

divisor = (root<<1) + 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 是奇数,设m=2*k+1,

那么 pow(2,k) <= N < pow(2, 1/2+k) < pow(2, k+1),

n-1=k, n=k+1=(m+1)/2

如果 m 是偶数,设m=2k,

那么 pow(2,k) > N >= pow(2, k-1/2) > pow(2, k-1),

n-1=k-1,n=k=m/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) // 被开方数,开方结果也为0

return 0;

N = 0;

tmp = (M >> 30); // 获取最高位:B[m-1]

M <<= 2;

if (tmp > 1) // 最高位为1

{

N ++; // 结果当前位为1,否则为默认的0

tmp -= N;

}

for (i=15; i>0; i--) // 求剩余的15位

{

N <<= 1; // 左移一位

tmp <<= 2;

tmp += (M >> 30); // 假设

ttp = N;

ttp = (ttp<<1)+1;

M <<= 2;

if (tmp >= ttp) // 假设成立

{

tmp -= ttp;

N ++;

}

}

return N;

}

以上都是网络查找的资料,有些晦涩难懂,不过在实际运用中可以使用这些算法。

单片机c语言6种开方,单片机快速开平方的算法相关推荐

  1. 51单片机c语言试题及答案,单片机C语言期末考试题..

    单片机C语言期末考试题..,单片机的c语言应用程序设计,单片机c语言编程,51单片机c语言程序100例,单片机c语言,单片机c语言编程思想,c语言开发单片机,c语言单片机程序,新概念51单片机c语言教 ...

  2. 单片机c语言三种经典程序结构,单片机C语言程序的结构和设计精选.docx

    单片机C语言程序的结构和设计精选 实验五 单片机C语言程序的结构和设计一.实验目的1. 掌握单片机C语言的程序结构:2. 掌握单片机C语言程序的编写和调试方法:3. 掌握MSP430FG2553基本I ...

  3. pic单片机c语言存储器定义,PIC单片机C语言程序设计1 7.PDF

    PIC单片机C语言程序设计1 7 学电子跟我来FOLLOW ME PIC 单片机C 语言程序设计(1) ◆ 丁锦滔 编者按:为了帮助具有PI C 单片机汇编语言知识的技术人员或工程师,快速掌握利用C ...

  4. 单片机快速开平方的算法

    C语言中开平方的算法中要开平方的话,可以在头文件中加#include <math.h>.然后调sqrt(n);函数即可.但在单片机中要开平方.可以用到下面算法: 算法1: 本算法只采用移位 ...

  5. 单片机c语言 i%3c%3c1,单片机C语言作业及上机习题及答案

    <单片机C语言作业及上机习题及答案>由会员分享,可在线阅读,更多相关<单片机C语言作业及上机习题及答案(37页珍藏版)>请在人人文库网上搜索. 1.第一次课熟悉winTC编译环 ...

  6. 单片机c语言模块化实例程序设计,单片机C语言模块化设计

    原标题:单片机C语言模块化设计 keil中实现 模块化编程.doc 在使用 KEIL 的时候,我们习惯上在一个.c 的文件中把自己要写的东西按照 自己思路的顺序进行顺序书写.这样是很普遍的写法,当程序 ...

  7. 51单片机c语言学习感想,51单片机实训心得体会

    [www.hywsbj.com--心得体会] 单片机实训有哪些心得体会呢?下面是小编为大家收集的资料,欢迎阅读哦. 51单片机实训心得体会 通过为期一周的单片机实训,是我们对这门课有了许多新的了解,弥 ...

  8. 51单片机c语言工作手册,51单片机C语言编程手册

    51单片机C语言编程手册 1 第一章 介绍 这是一本关于Intel 80C51 以及广大的51 系列单片机的书这本书介绍给读者一些 新的技术使你的8051 工程和开发过程变得简单请注意这本书的目的可不 ...

  9. 单片机c语言 〉〉,PìC单片机C语言编程入门(课件).doc

    PìC单片机C语言编程入门(课件) PICC入门笔记 PIC单片机C语言编程入门笔记 C语言基础复习--------没C语言基础看起来可能有点困难. C程序的语句 语句名称一般形式说明表达式语句表达式 ...

  10. 单片机c语言如何表示二进制,单片机C语言中将二进制数转化为十进制的办法

    单片机C语言中将二进制数转化为十进制的办法 1.最简单最直观的方法,将2进制方式表示的数转化为10进制表示的数,要用除10取余法,步骤如下 被除数记为x,10进制表示的结果用数组a表示 1. i=0; ...

最新文章

  1. 文件系统演示C语言,基于C语言的简单文件系统的实现
  2. Kohana中控制器继承自Controller_Template的问题
  3. 如何定位消耗CPU最多的线程
  4. input 单选框ajax提交,input radio单选框绑定change事件
  5. ETL工具 kettle问题
  6. 计算机控制系统的概念构成,计算机控制系统复习
  7. vs code html table,vs Code 快速生成代码
  8. Python三维绘图--Matplotlib colorbar生成
  9. 穷人怎么慢慢打破阶层?做到这2点,活出最真实的样子,别表演!
  10. php mysql源码包,linux下Apache+PHP+mysql+phpMyAdmin源码包安装配置
  11. Dijkstra(堆优)模板
  12. HA模式下的java api访问要点
  13. Linux中的Tomcat500异常,Linux处理Tomcat异常的方法
  14. paddle2.0实现DNN(minst数据集)
  15. 微软的补丁服务器,Microsoft 安全公告 MS17-010 - 严重
  16. Linux创建.txt文件
  17. 720nopenwrt设置打印服务器_TP-Link_TL-WR703N网络打印服务器
  18. java httpclient 调用webservice_HttpClient调用WebService接口
  19. How to create swiping gesture list items for Windows Phone 7
  20. 更改MyEclipse匹配颜色

热门文章

  1. PPT太大怎么进行压缩
  2. 【Unity插件001】VRTK3.3.0的使用
  3. 【第三方支付通道】第三方支付接口如何对接?
  4. 老路MBA商学课|第003课:沉没成本|因为来都来了,所以将错就错
  5. 入门图形学:ComputeShader
  6. ipv4v6双栈技术_什么是IPv6双栈技术
  7. linux终端无法输入大写字母,linux不能打大写字母
  8. java 图片怎么设置抗锯齿,图片变形的抗锯齿处理方法
  9. ORA-00001: 违反唯一约束条件
  10. 用termux打开python文件,安卓手机运行python程序的软件:Termux、Pydroid3