有人提到过这个问题,我却无法回答,求高手帮忙!
vb吧
全部回复
仅看楼主
level 1
在VB里,如何实现对X开平方?即spr(x)函数的原型是什么?我当时就想到用泰勒公式,但是等我开始编程的时候发现,用这个公式,里面也要用到spr(x),于是不知道怎么办好了...求高手帮助解决,最好贴出源代码!
2006年08月13日 09点08分 1
level 0
就是二次根号下X,X>=0运算优先级和幂一样
2006年08月13日 10点08分 2
level 1
我看了之后第一个想法是:举个例子用一个,个位数乘以自己,大了,就减一,一直减到小了为止,然后再减0.1,再自己和自己乘,依此类推,你想几位就能算出几位,哈哈~~哈哈~~~不要歧视我的想法啊
2006年08月13日 10点08分 3
level 1
想法不错,就是不知道运行起来效率怎样,我想会很恐怖吧?-_-!其他人继续!sqr(x)的原型!
2006年08月13日 10点08分 4
level 1
继续啊
2006年08月13日 16点08分 5
level 1
二分法求解,取其一半自乘,误差大于规定的数就继续,比如:spr(49)=24*24〉4912*12〉496*6〈49 9*9>497*7=49所以,spr(49)=7这个方法比3楼的要好吧。大家继续
2006年08月13日 18点08分 6
level 1
用牛顿迭代吧
2006年08月14日 08点08分 7
level 1
查表法!哈哈
2006年08月14日 08点08分 8
level 0
有比较好的方法原理是x^2+20xy +100y^2 =(x+10y)^2只需要准备 1-9 的 平方 就可以了跟笔算开方一个方法算出第一位后余数*5除第一位后 得出数 上下错一就基本上是第二位数要算几位算几遍^^类似87=81+66*100/9*20 =3....余数是8700-93*93=51 51*5/93=2....1376余数是 1376*5/932=7.... 如此^^最简算法吧第1步可以再用二分法简化 哈哈借鉴下6楼经验
2006年08月14日 09点08分 9
level 1
不知道9楼写的是什么?怎么乱七八糟的?
2006年08月14日 10点08分 10
level 0
无奈,只要写代码了表达能力差,被人鄙视了 哭 5555555555其实我的这个很接近sqrt()源码的.....很多函数忘记,我用代替的做了,懒的去查这里仅仅 用来算一位数的开方精确到 0.01.....其他代码你自己补全吧 怒了,居然鄙视我a,b,c,d,e,i :integer;//d 是 结果的某位小数部分 a是结果 b 是 你输入的数 c是 计算过程中用到的数b:=6e:=1a:=2c:=b-a*awhile (b-a*a)>0.01 dobeginc:=c*100^ed:=c/(a*20) //这里算出的d 是 取整数 非4舍5入嘎嘎if (b-(a+d*(0.1)^e)*(a+d*(0.1)^e))<0 then begin d:=d-1 //有些时候算的数比想要的数大1 end a:=a+d*(0.1)^e //0.1的e次方 自己写吧 函数忘记e:=e+1c:=b-a*aend;哼哼自己去读吧写点原理 居然不仔细看
2006年08月15日 03点08分 11
level 0
错了点c 必须是 实数 不能是整数嘎嘎
2006年08月15日 03点08分 12
level 2
John Carmack 密码:0x5f3759df有人在Quake III 的源代码里面发现这么一段用来求平方根的代码:/*================SquareRootFloat================*/float SquareRootFloat(float number) {long i;float x, y;const float f = 1.5F;x = number * 0.5F;y = number;i = * ( long * )&y;i = 0x5f3759df - (i >> 1 ); // 注意这一行y = * ( float * )&i;y = y * ( f - ( x *y * y ) );y = y * ( f - ( x *y * y ) );return number * y;}0x5f3759df? 这是个什么东西? 学过数值分析就知道,算法里面求平方根一般采用的是无限逼近的方法,比如牛顿迭代法,抱歉当年我数值分析学的太烂,也讲不清楚。简单来说比如求5 的平方根,选一个猜测值比如2 ,那么我们可以这么算5/2 = 2.5; 2.5+2/2 = 2.25; 5/2.25 = xxx; 2.25+xxx/2 = xxxx ...这样反复迭代下去,结果必定收敛于sqrt(5),没错,一般的求平方根都是这么算的。而卡马克的不同之处在于,他选择了一个神秘的猜测值0x5f3759df 作为起始,使得整个逼近过程收敛速度暴涨,对于Quake III 所要求的精度10 的负三次方,只需要一次迭代就能够得到结果。好吧,如果这还不算牛b ,接着看。普渡大学的数学家Chris Lomont 看了以后觉得有趣,决定要研究一下卡马克弄出来的这个猜测值有什么奥秘。Lomont 也是个牛人,在精心研究之后从理论上也推导出一个最佳猜测值,和卡马克的数字非常接近, 0x5f37642f。卡马克真牛,他是外星人吗?传奇并没有在这里结束。Lomont 计算出结果以后非常满意,于是拿自己计算出的起始值和卡马克的神秘数字做比赛,看看谁的数字能够更快更精确的求得平方根。结果是卡马克赢了... 谁也不知道卡马克是怎么找到这个数字的。最后Lomont 怒了,采用暴力方法一个数字一个数字试过来,终于找到一个比卡马克数字要好上那么一丁点的数字,虽然实际上这两个数字所产生的结果非常近似,这个暴力得出的数字是0x5f375a86。Lomont 为此写下一篇论文,"Fast Inverse SquareRoot" 。John Carmack, ID的无价
2006年08月15日 03点08分 13
level 1
看样子我智商实在是太低了,11楼的和13楼的,看了N遍我都看不懂,希望谁能来解释下。还用C语言,我晕。我看了看又不象C语言。请用VB完整无误的贴个代码吧。
2006年08月15日 06点08分 14
level 2
hoho,以前数学书上有讲这种方法比较经典吧假设被开放数为a,如果用sqrt(a)表示根号a 那么((sqrt(x)-sqrt(a/x))^2=0的根就是sqrt(a) 变形得 sqrt(a)=(x+a/x)/2 所以你只需设置一个约等于(x+a/x)/2的初始值,代入上面公式,可以得到一个更加近似的值,再将它代入,就得到一个更加精确的值……依此方法,最后得到一个足够精度的(x+a/x)/2的值。 如:计算sqrt(5) 设初值为2 1)sqrt(5)=(2+5/2)/2=2.25 2)sqrt(5)=(2.25+5/2.25)/2=2.236111 3)sqrt(5)=(2.236111+5/2.236111)/2=2.236068 这三步所得的结果和sqrt(5)相差已经小于0.001你再上百度搜一下 "笔算开平方" 还有大把方法
2006年08月15日 06点08分 15
level 0
呵呵,偶是9楼 11楼的看了诸位的帖子拿走也13楼的算法应该是精度低时速度最快的算法了我的算法 是单向运算的算法而我的算法在万位以上精度运算估计有显著优势^^毕竟我的运算 是一次算一位而他们的算法 则是 不断 递归
2006年08月15日 09点08分 16
level 1
kusoben ,谢谢了。 奇怪了,印象中怎么没学过呢?难道我的记性真的这么差,或者上数学课上开小差了?这是几年级的数学课学的“笔算开平方”?
2006年08月16日 09点08分 17
level 1
估计还有和我一样不明白的人,为了方便,现在把13楼的方法(也就是15楼的方法)的原理在下面举例说明一下。开平方 例:(以20为例) 16=4*4 设20=(4+x)^2 20=16+8x+x^2 因为x较小 所以 20约等于16+8x x约等于0.5 设20=(4.5+x)^2 同理 x约等于-0.0277 ............... 开立方例:(以20为例) 27=3*3*3 20=(3-x)^3 20约等于27-27x x约等于0.259 .........
2006年08月16日 10点08分 18
level 1
经过我亲自实验,采用二分法(6楼)和15楼的(笔算开平方法)的比较.有以下几点.1,运算时间,这个无法测试,因为运算速度都在1毫秒以内,而NT系统的时间准确度却在10ms左右.sleep和timer等在NT中都是10毫秒左右,API也是.98系统是55毫秒左右2,循环次数,在数值比较小的时候,笔算开平方法相当少的次数就可以出结果(精度都是10的-11次方),二分法却大概要40次左右才能出来,但是数值比较大时,比如33333333333(11个3)二分法可以很快(60几此循环)出结果,而笔算开平方法基本无限循环,(也不知会不会出结果)希望大家研究一下,下面是两种方法的VB完整源代码.二分法: Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As LongPrivate Sub Command1_Click()Dim x
#, X1#
, X2
#, Y#
, Y1
#, n#
, cot As LongConst E = 0.00000000001x = Val(Text1)X1 = xX2 = 0cot = GetTickCount()DoY1 = (X1 + X2) / 2Y = Y1 * Y1If Y - x > E ThenX1 = (X1 + X2) / 2ElseIf Y - x < -E ThenX2 = (X1 + X2) / 2ElseExit DoEnd Ifn = n + 1If n = 10000000 Then Exit DoLoopcot = GetTickCount() - cotPrint "用时" + Str(cot) + "毫秒"Print "循环" + Str(n) + "次"Text1.Text = Trim(Str(Y1))End Sub笔算开平方法: Option Explicit Private Declare Function GetTickCount Lib "kernel32" () As LongPrivate Sub Command1_Click()Dim x
#, X1#
, X2
#, Y#
, Y1
#, n#
, cot As LongConst E = 0.00000000001x = Val(Text1)cot = GetTickCount()If x = 1 ThenY = 1ElseX1 = x / 2X2 = 0DoY1 = x - X1 * X1If Y1 > E Or Y1 < -E ThenX2 = X1X1 = Y1 / (2 * X1)X1 = X1 + X2ElseExit DoEnd Ifn = n + 1If n = 10000000 Then Exit DoLoopEnd Ifcot = GetTickCount() - cotPrint "用时" + Str(cot) + "毫秒"Print "循环" + Str(n) + "次"Text1.Text = Trim(Str(X1))End Sub也许我的算法并不正确,希望高手贴个spr(x)的VB完整源代码
2006年08月16日 17点08分 19
level 0
Function Sqr(Number As Double) As DoubleSqr=Number^0.5End Function呵呵,这样效率最高
2007年07月25日 03点07分 20
1 2 尾页