易码技术论坛

 找回密码
 加入易码
搜索
查看: 691283|回复: 23

如何实现开方运算(在WQX上)

[复制链接]
发表于 2006-12-24 18:20:35 | 显示全部楼层
楼主是说用GV-BASIC开平方吗?
  1. REM 比如把4开平方。。
  2. 4^(1/2)
  3. REM 结果为2。。
复制代码
发表于 2006-12-25 10:13:08 | 显示全部楼层
一般是采用牛顿迭代法,不过在一些低精度要求下可采用位操作求近似值。

psS -__________-b
 楼主| 发表于 2006-12-26 21:12:25 | 显示全部楼层
是说那种高精度的运算,不是简单的SQR那样的哦
发表于 2006-12-26 21:32:22 | 显示全部楼层
采用手工开方原理,精度再高也没问题.只是在WQX上速度会很龊滴~

还是牛顿迭代法比较好,下面这个应该看过吧
  1. int sqrt(long M)
  2. {
  3. int N, i;
  4. long tmp,ttp;
  5. if(M==0) return 0;
  6. N=0;
  7. tmp =(M>>30);
  8. M=M<<2;
  9. if(tmp > 1)
  10. {
  11. N++;
  12. tmp=tmp-N;
  13. }
  14. for(i=15;i>0;i--)
  15. {
  16. N=N<<1;
  17. tmp=(tmp<<2)-(M<0)*2+((M&0x7fffffff)>>30);
  18. ttp=(N<<1)+1;
  19. M=M<<2;
  20. if(tmp>=ttp)
  21. {
  22.   tmp=tmp-ttp;
  23.   N++;
  24. }
  25. }
  26. return N;
  27. }
  28. void main()
  29. {
  30. int t;
  31. printf("10000的平方根为%d",sqrt(10000));
  32. getchar();
  33. }
复制代码
 楼主| 发表于 2006-12-30 20:02:04 | 显示全部楼层
多谢,试去了...
 楼主| 发表于 2007-1-6 17:16:01 | 显示全部楼层
不行啊.
经测试精度太低了,还不到BAS的呢...
才1位:
SQR(2)=1...
汗之
发表于 2007-1-6 17:48:13 | 显示全部楼层
本人有写过一个代码,要到几位自己调,等一下我把星星上的代码传上来,测试小数点后4位还可以。

代码如下:

void main()
{char j,ws;
long kf;
long buf;
long i,tmp;
long wsj;
kf=3;
buf=kf;
ws=9;
wsj=10;
while(j<ws&&Inkey()!=27)
{if(i*i>buf)
  {j++;
  buf=100*buf;
  if(j==1){tmp=i-1;}
  if(j==ws){i=i-1;break;}else{i=10*(i-1);}
  }
  i++;
}
for(j=0;j<ws-2;j++)
{wsj=10*wsj;}
SetScreen(1);
printf("%d开方:%d.%d",kf,tmp,i-wsj*tmp);
Delay(5000);
exit(0);
}

不知道合不合适,我自己想到的,没有优化和其他,结果和科学计算器的一样。
 楼主| 发表于 2007-1-6 19:44:06 | 显示全部楼层
测试了下:
很不错
请问原理
P.S:如果可以来份BAS版的,比较简单啊(刚开始学C啊)
发表于 2007-1-6 20:55:55 | 显示全部楼层
这个也不是什么原理啦,就是用逼近法。
比如开方35:
一直进行累乘,乘到6×6>35,说明个位是5。
然后把数据乘以100,35×100=3500,
从50开始累乘,得到:60×60>3500,所以小数后一位是9,得到5.9。
然后继续重复上诉步骤。

因为LAVA没有浮点小数,所以用放大的方法来求开放数。

就这样一位一位地乘出来,每一位最多乘上10次,所以很大的数也不用怕。(优化的话可以从十位/百位等乘起)比如我开到4位,顶多进行40次运算(不计个位数字),运算量并不大,所以速度还可以。
 楼主| 发表于 2007-1-8 20:15:40 | 显示全部楼层
THANKS.
但我把代码里的while(j<4&&Inkey()!=27)
写成while(j<20&&Inkey()!=27)

位数增加,但数字却不对了.
发表于 2007-1-9 12:02:20 | 显示全部楼层
在计算平方根为整数时会有一些不理想!如
   __
√64=8.1
发表于 2007-1-9 16:14:05 | 显示全部楼层
那个叠代法真的好经典!很多C语言的课本上都有这个
发表于 2007-1-9 18:23:39 | 显示全部楼层
计算成整数的时候是因为我忘记判断跳出了。
在代码那里加一句
if(j==4){break;}

就解决了。(记得修改这个,不然就会算错了)

开到20位的话估计是不够位数了,因为long型顶多是
-2147483648~2147483647
这个范围啊,那个计算20位小数应该超出范围了,所以不对了。
(只是我的猜测而已啊……)

还有就是你还要修改printf那里的计算,4位是100000×tmp,就是比要的位数多1位才行,今天试着计算到8位,还没有出问题。

我修改了代码,就在第7楼,你记得改啊。这回应该没有问题了吧?等等我试一下开到20位看看情况。
 楼主| 发表于 2007-1-11 21:04:02 | 显示全部楼层
最近找到一个方法,可以无限求,不需要扩大等.
徒手开n次方根的方法:
原理:设被开方数为X,开n次方,设前一步的根的结果为a,现在要试根的下一位,设为b,
则有10*a+b)^n-(10*a)^n<=c(前一步的差与本段合成);且b取最大值
用纯文字描述比较困难,下面用实例说明:
我们求 2301781.9823406 的5次方根:
第1步:将被开方的数以小数点为中心,向两边每隔n位分段(下面用&#39;表示);不足部分在两端用0补齐;
23&#39;01781.98234&#39;06000&#39;00000&#39;00000&#39;..........
从高位段向低位段逐段做如下工作:
初值a=0,差c=23(最高段)
第2步:找b,条件10*a+b)^n-(10*a)^n<=c,即b^5<=23,且为最大值;显然b=1
差c=23-b^5=22,与下一段合成,
c=c*10^n+下一段=22*10^5+01781=2201781
第3步:a=1(计算机语言赋值语句写作a=10*a+b),找下一个b,
条件10*a+b)^n-(10*a)^n<=c,即:(10+b)^5-10^5<=2201781,
b取最大值8,差c=412213,与下一段合成,
c=c*10^5+下一段=412213*10^5+98234=41221398234
第4步:a=18,找下一个b,
条件:(10*a+b)^n-(10*a)^n<=c,即:(180+b)^5-180^5<=41221398234,
b取最大值7
说明:这里可使用近似公式估算b的值:
当10*a>>b时,(10*a+b)^n-(10*a)^n≈n*(10*a)^(n-1)*b,即:
b≈41221398234/n/(10*a)^(n-1)=41221398234/5/180^4≈7.85,取b=7
以下各步都更加可以使用此近似公式估算b之值
差c=1508808527;与下一段合成,
c=c*10^5+下一段=1508808527*10^5+06000=150880852706000
第5步:a=187,找下一个b,
条件:(10*a+b)^n-(10*a)^n<=c,即:
(1870+b)^5-1870^5<=150880852706000,
b取最大值2,差c=28335908584368;与下一段合成,
c=c*10^5+下一段=2833590858436800000
第6步:a=1872,找下一个b,
条件:(10*a+b)^n-(10*a)^n<=c,即:
(18720+b)^5-18720^5<=2833590858436800000,
b取最大值4,差c=376399557145381376;与下一段合成,
c=c*10^5+下一段=37639955714538137600000


而且可以解N次方根...
发表于 2007-1-11 22:20:10 | 显示全部楼层
只要用long数组取代long,这个也是可以实现的,结果只能充当printf的返回值,只用long的话,我那个貌似顶多开到10位,不然不够位了。
发表于 2007-1-12 21:53:47 | 显示全部楼层
好复杂的说.
发表于 2007-1-12 23:15:10 | 显示全部楼层
一个Math.sqrt就解决了
发表于 2007-1-14 02:39:27 | 显示全部楼层
一般计算机上会采用牛顿迭代吧,或者别的什么迭代法
发表于 2007-1-14 09:43:40 | 显示全部楼层
多项式展开
 楼主| 发表于 2007-1-14 15:23:53 | 显示全部楼层
如何展开?
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-19 20:43 , Processed in 0.013679 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表