不用SQRT开平方的C++代码

来源:互联网 发布:2016中国经济发展数据 编辑:程序博客网 时间:2024/05/16 09:21
定义  求一个数a的平方根的运算,叫做开平方(extraction of square root),其中a叫做被开方数。
  a必须大于或等于零,即a为非负数
  开方公式
  X(n + 1) = Xn + (A / Xn – Xn)1 / 2.。(n,n+1与是下角标)
  开平方的理论依据
  开平方是平方的逆运算,只要我们知道平方的计算方法,开平方就迎刃而解了。
  我们令10位数值为A,个位数值为B,即为A*10+B,根据二数和的平方有:
  (A*10+B)^2=(A*10)^2+2(A*10)*B+B^2=(A^2)*100+(20A+B)*B。
  举例说明:例359^2计算方法
  1、3^2=9,
  2、(20*3+5)*5=325,
  3、(20*35+9)*9=6381,
  4、将这些数,按两位分节合起来:90000+32500+6381=128881。得359^2=128881。
  将这些计算步骤倒过来,就是开平方。同理,可以得开立方及N次方的方法。

编辑本段开方的计算步骤

  1.将被开方数的整数部分从个位起向左每隔两位划为一段,用撇号分开(竖式中的11’56),分成几段,表示所求平方根是几位数;
 笔算开平方方法

笔算开平方方法

  2.根据左边第一段里的数,求得平方根的最高位上的数(竖式中的3);
  3.从第一段的数减去最高位上数的平方,在它们的差的右边写上第二段数组成第一个余数(竖式中的256);
  4.把求得的最高位数乘以20去试除第一个余数,所得的最大整数作为试商(20×3除256,所得的最大整数是 4,即试商是4);
  实例 开方公式
  X(n + 1) = Xn + ( Xn – Xn)1 / 2.。(n,n+1与是下角标)
  例如,A=5:
  5介于2的平方至3的平方;之间。我们取初始值2.1,2.2,2.3,2.4,2.5,2.6,2.7,2.8,2.9都可以,我们最好取 中间值2.5。
  第一步:2.5+(5/2.5-2.5)1/2=22;输入值大于输出值,负反馈;
  即5/2.5=2,2-2.5=-0.5,-0.5×1/2=-0.25,2.5+(-0.25)=2.25,取2位数2.2。
 

  第二步:2.2+(5/2.2-2.2)1/2=2.23;输入值小于输出值,正反馈;
  即5/2.2=2.27272,2.27272-2.2=0.07272,0.07272×1/2=0.03636,2.2+0.03636=2.23636。取3位数2.23。
  第三步:2.23+(5/2.23-2.23)1/2=2.236。
  即5/2.23=2.2421525,,2.2421525-2.23=0.0121525,,0.0121525×1/2=0.00607,,2.23+0.006=2.236.,取4位数。
  每一步多取一位数。这个方法又叫反馈开方,即使你输入一个错误的数值,也没有关系,输出值会自动调节,接近准确值。
  例如A=200.
  200介如10的平方---20的平方之间。初始值可以取11,12,13,14,15,16,17,18,19。我们去15.
  15+(200/15-15)1/2=14。取19也一样得出14.。:19+(200/19-19)1/2=14.。
  14+(200/14-14)1/2=14.1。

  14.1+(200/14.1-14.1)1/2=14.14.

//为了取第一个靠近值,网上学习的一个开方整数的函数//该函数能算出目标值的整数位,在此用来计算我们要取的第一个目标值unsigned long sqrt_16(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 root;//(unsigned short)(root);}float sqrt_new(float m){ unsigned long s=0; float t=0.0;  if (m>=1.00) {  s=sqrt_16(unsigned long(m));  t=s+(m/s-s)/2; } else {  t=float(0.4);  t=t+(m/t-t)/2;  //牛顿切线法    t=t+(m/t-t)/2;  //次数越多,精度越高  t=t+(m/t-t)/2;    t=t+(m/t-t)/2;  //精确可以在0.0001开方 }// t=t+(m/t-t)/2; t=t+(m/t-t)/2; t=t+(m/t-t)/2; return t;}void main(){ while(1) {  float x;  cout<<"Please input a num:";  cin>>x;  cout<<sqrt_new(x)<<endl;  cout<<sqrt(x)<<endl; }}


 

原创粉丝点击