算法求解:计算实数的平方根,要求精确到小数点后64位。

leio 2006-02-18 05:19:59
pb中的数据类型decimal,double,float,real的精度都不够(其它语言中的数据类型估计也不够)。

求一算法可以精确计算X(X为整数)的平方根,能算出小数点后64位数字。

用PB自带的SQRT最多只能精确到小数点后15数字(double类型),X若大于100,精度则小于15位。
用WindowsXP自带的计算器,最多只能精确到小数点后32位数字,X若大于100,精度则小于32位。

本人文科,不懂高深的数学理论,除了查表或用计算器,至今不知如何手工计算平方根:-S
用google搜索了一下关于平方根的算法,看不懂什么“泰勒级数”,“牛顿迭代法”。

会算法的帮个忙

谢谢


...全文
1208 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
WorldMobile 2006-02-20
  • 打赏
  • 举报
回复
1、我如何来计算平方根?
比如“根号2”=1.4142135623730950488016887242097........(这个值我是用XP的计算器得出来的)。我怎么算出小数点后第一位就是4,第二位就是1。
答:用循环,见你的第二个问题

2、“字符串相乘”,难道你是要我遍历所有可能的组合然后计算其平方值是否等于我要计算的X?
比如我要算“根号2”,假设只要精确到小数点后一位。是不是让我计算1.1,1.2,1.3,1.4,1.5,.16,1.7,1.8,1.9的平方值,然后取其中最接近2的一个?
答:是的,我的意思就是这么个意思,笨是笨了点,但速度肯定不会太慢,因为你也就是计算64位,即执行640次,先计算小数点后一位,然后再计算第二位等

我不知道古人是怎么算的,在没有电脑的情况下,手工算出“根号2”。我现在想要知道的就是如何在只有纸笔的情况下来计算平方根,并且要精确到小数点后64位。

手工开平方根,我也会,但要写成计算机语言,比较麻烦,建议用那个比较简单的算法,如果你觉得不好,改天我写个算法放上来,呵呵
renwanly 2006-02-20
  • 打赏
  • 举报
回复
表示关注!
wguxin 2006-02-20
  • 打赏
  • 举报
回复
找资料写了个

声明函数
function f_get_rt(ulong as_num,ulong as_ys,integer strlen,ref string ref_str)
return integer
// as_num 中间结果
// as_ys 余数
// strlen 长度
// ref_str 结果

long ll_num,ll_ys,ll_temp

ll_num = 2*10*as_ys

ll_ys = Truncate(as_num/ll_num,0)

do while ll_ys*(ll_ys + ll_num) > as_num
ll_ys = ll_ys - 1
loop

ll_temp = as_num - ll_ys*(ll_ys + ll_num)
ll_temp = ll_temp * 100

ref_str = ref_str + string(ll_ys)
do while len(ref_str) < strlen
ll_ys = long(string(as_ys) + string(ll_ys))
f_get_rt(ll_temp,ll_ys,strlen,ref_str)
loop

return len(ref_str)

使用 : 比如算10的平方根

string ls_len
integer i,li_num,li_ys,li_n

li_n = 10
li_ys = TruncateSqrt(li_n),0)//整数部分
li_num = (li_n - li_ys*li_ys)*100
f_get_rt(li_num,li_ys,16,ls_len)//16 为要返回的小数位数 结果在 ls_len 中


我用PB6.5 测试通过但是由于PB的限制 (ulong 最大只能到 4,294,967,295 ,益出) 只能算到大概6位左右
公式参考:

条件:N(N+2*Q*R) <=Y
n进制时,Q=n;R为上一次的结果;N为要试的满足条件的最大的值;Y为计算到这时的余数
(注意:补位时要看进制,如果为10进制,则应补100,即10*10;二进制时应补4,即2*2)

例1:10开方根(10进制)
sqrt(10)=3.1622776601683793319988935444327

3. 1 6 2
)10
9 <=N(N+2*Q*R)=3*(3+2*10*0)=9<10 上 3
1 00
61 <=N(N+2*Q*R)=1*(1+2*10*3)=61<100 上 1
39 00
37 56 <=N(N+2*Q*R)=6*(6+2*10*31)=3756<3900 上 6
1 44 00
1 26 44 <=N(N+2*Q*R)=2*(2+2*10*316)=12644<14400 上 2
17 56
....


ckc 2006-02-20
  • 打赏
  • 举报
回复
不知道你要做什么,有些语言带了高精度函数库,可以满足你的要求,比如下面的a.php
<?php
echo bcsqrt("2",64);
?>
然后用php调用 php a.php就可以得到结果
1.4142135623730950488016887242096980785696718753769480731766797379
事实上我们可以用这个方法计算更多的位数,试下640位
1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727350138462309122970249248360558507372126441214970999358314132226659275055927557999505011527820605714701095599716059702745345968620147285174186408891986095523292304843087143214508397626036279952514079896872533965463318088296406206152583523950547457502877599617298355752203375318570113543746034084988471603868999706990048150305440277903164542478230684929369186215805784631115966687130130156185689872372352885092648612494977154218334204285686060146824720771435854874155657069677653720226485447015858801620758474922657226002085584466521458398893
如果你非要用pb的话,可以考虑用php的函数run调用一个php来计算出你的结果,php把结果放到文件或者数据库中,然后你再去读文件或者数据库好了
jiangxj 2006-02-20
  • 打赏
  • 举报
回复
古人的方法需用到多位数的乘法和减法,是decimal精度不够的.
当然,可以先定义乘法和减法函数再求开方.但很复杂.
bbdx2523 2006-02-20
  • 打赏
  • 举报
回复
帮你顶
那些算法学过,现在忘了,说了=没说
leio 2006-02-20
  • 打赏
  • 举报
回复
如果只是要结果,用 ckc(火) 的方法不错,装个PHP环境就搞定了。

编程的话,lzp_lrp(lzp) 的思路比较好理解,这两天就来试试。不过,这的确是个很笨的方法。:D

wguxin() 的方法看起来挺麻烦的,而且受ulong的限制只能算6位,我以后有空再研究用字符串方式来计算更多位数。


多谢各位,结贴。
leio 2006-02-19
  • 打赏
  • 举报
回复
to lzp_lrp
我知道不可能用数值变量来实现,必然是要采用字符串。但问题是:
1、我如何来计算平方根?
比如“根号2”=1.4142135623730950488016887242097........(这个值我是用XP的计算器得出来的)。我怎么算出小数点后第一位就是4,第二位就是1。
2、“字符串相乘”,难道你是要我遍历所有可能的组合然后计算其平方值是否等于我要计算的X?
比如我要算“根号2”,假设只要精确到小数点后一位。是不是让我计算1.1,1.2,1.3,1.4,1.5,.16,1.7,1.8,1.9的平方值,然后取其中最接近2的一个?

我不知道古人是怎么算的,在没有电脑的情况下,手工算出“根号2”。我现在想要知道的就是如何在只有纸笔的情况下来计算平方根,并且要精确到小数点后64位。当然,如果能用PB语言(其它语言也行)表达出来更好。就好比古人计算圆周率,是用多边形无限逼近圆来计算圆周率那样。

就如我提问时说的那样,我是文科,没学过“高级”的数学知识,所以就把我当成是古人吧,用“古人”的方式来计算“根号2”吧。
WorldMobile 2006-02-18
  • 打赏
  • 举报
回复
写一个函数实现两个字符串相乘,然后用循环来逐位计算,思路基本如此,你自己想想吧
WorldMobile 2006-02-18
  • 打赏
  • 举报
回复
用数值变量肯定没法实现,建议你用字符串来存数字,然后再写算法实现
WorldMobile 2006-02-18
  • 打赏
  • 举报
回复
不太麻烦

740

社区成员

发帖
与我相关
我的任务
社区描述
PowerBuilder 脚本语言
社区管理员
  • 脚本语言社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧