注册 登录
编程论坛 VFP论坛

笔算开平方转化成vfp程序

独木星空 发布于 2022-08-20 23:27, 2244 次点击
今天给一个当家的中学生讲解了笔算开平方,初中都接触了\((a+b)^2=a^2+2ab+b^2\),  假设ab表示一个广义2位数,b代表个位数,a代表十位数,则ab=10a+b,然后\((10a+b)^2=100a^2+20ab+b^2\),  我们理解不清时,把100a不去考虑,仅仅考虑20ab+\(b^2\)形式,提出公因子b,则为20a+b,然后先以20a作为试商,开始第一步不用考虑,只考虑某一个数的平方即可,从第二步,考虑(20a+b)*b的值,以20a作为先前考虑的倍值,忘了说一件事情,笔算开平方,与多位数除法类似,只不过,第一步是先划分,从个位开始,两位数划分一个段落,确定开方数是几位数,划分的段落数即为开方数的位数,与多位数除法不同之处,多位数除法每次是一位一位的下拉,而笔算开平方是两位两位的下拉。现在讲解一个实例,比如125笔算开平方,先划段,1,25,说明开出来的方值是两位数的,第一步是1,1*1=1,所以第一个数上1,1-1=0,把25拉下来,这时,a=1,20a=20,25除20,最大试商是1,另b=1,20a+b=20*1+1=21,(20a+b)*b=21*1=21,25-21=4,补两位数,变成400,这时a=11,20a=220,用220作为试商,400/220=1.多,所以最大试商是1,20a+b=20*11+1=221,(20a+b)*b=221*1=221,400-221=179,再补两位数,变成17900,这时a=111,20a=2220,以2220作为试商,17900/2220=8.063,最大试商是8,另b=8,20a+b=111*20+8=2228,2228*8=17824,17900-17824=76,再次增加两位,变成7600,这时a=1118了,20a=22360,显然7600不是它的倍数,那么只能再扩大2位数,变成760000,........,一直下去,直到满足有效位即可(笔算开平方时要求精确到的位数)。

[此贴子已经被作者于2022-8-21 19:28编辑过]

19 回复
#2
独木星空2022-08-21 00:22
建一种算法,必须对原理熟悉,陌生方面的肯定难于着手。
#3
独木星空2022-08-22 21:00
人们对笔算开平方并不感兴趣,因为有开方函数(不同软件中一般应该自带)。
#4
独木星空2022-08-23 20:41
没有人插手这个问题。如何上手是关键。
#5
独木星空2022-08-24 06:36
如果没有人发表点看法,这分结转给谁?看来,不能自己挖坑。
#6
独木星空2022-08-25 06:50
没有办法,只好终止悬赏。
#7
独木星空2022-08-27 20:43
有时把数学语言用程序翻译出来并不容易。
安照笔算开平方原理,(a+b)^2=a^2+2ab+b^2,把ab看成两位数,a占十位数,b占个位数,则广义二位数ab可写成10a+b的形式,那么(10a+b)^2=100a^2+20ab+b^2,我们暂时不要考虑高位的100a^2,仅仅考虑20ab+b^2,提出公因子b,小括里是(20a+b)这个式子,以20a作为试商,最大值不超9,然后逐步递减。
    当n=3时,原理一样,此时是:(a+b)^3=a^3+3a^2b+3ab^2+b^3,同样不要考虑最高位的a^3,如果也安广义2位数去理解,则把a用10a代替,其结果是1000a^3+300a^2b+30ab^2+b^3,去掉最高位的1000a^3,同样提出提出公因子b,则小括里(300a^2+30ab+b^2),以300a^2作为试商,同理是从个位开始划分段落,每三位一段,小数点后,每次增大三位数,即三位三位的下拉,这是与多位数除法不一致的地方。
     笔算开平方没有统一的模式,至于小数点的就不要强求了。
     知道方法就好,没有必要伤脑筋,2,3,4可以玩一玩,再高,笔算开方也没有多大实际意义。
#8
独木星空2022-08-27 20:43
这样玩的有点大,不过只要你有耐心,还是可以进行的。
无非就是(10a+b)^10=∑C(n,m)(10a)^(n-m)b^m,n=10,m∈[0,10],也就是11项连加,仍就撇开最高位的10^10*a^10,把后边的式子提出公共因子b来,然后以10*10^9a^9作为试商(最大值为9),试商后计算多项式的值,乘b后不大于拉下的值(每次增位是10位数),计算量有点大,可借助计算机(实际上借助计算机也无济于事,因为位数不够),光靠笔算,真是比登天还难,怕是用A4纸都不够看,要用8裁的纸才能写下,而且保留有效位数不能太多。
    所以,笔算开平方只是加强对二项式展开式的深度理解,这种苛刻的笔算开平方没有更多现实意义,玩它没有什么必要,降降级,玩个n=5,6的情形也可以,锻炼计算的马虎性。
#9
独木星空2022-08-27 20:44
我也没有细心计算,1.2^13=10.6993205379072
10.6993205379072,第一步,上个1(即,最高位是1,也就是a=1),不能上2,因为2的10次方是1024,从个位往高位划段,每10位数划分一段,10就能划分1段,所以,开方数是一个个位小数。第二步,就步入正规,10-1^10=9,然后拉下10位数,为96993205379,最大试商是2(3就是负数了)。
10a次方    b次方    C(10,i)    系数*(10a)^j    *a^j    *b^i    1    2    积
9    1    10    10000000000    a^9    b^1    1    2    20000000000
8    2    45    4500000000    a^8    b^2    1    4    18000000000
7    3    120    1200000000    a^7    b^3    1    8    9600000000
6    4    210    210000000    a^6    b^4    1    16    3360000000
5    5    252    25200000    a^5    b^5    1    32    806400000
4    6    210    2100000    a^4    b^6    1    64    134400000
3    7    120    120000    a^3    b^7    1    128    15360000
2    8    45    4500    a^2    b^8    1    256    1152000
1    9    10    100    a^1    b^9    1    512    51200
0    10    1    1    a^0    b^10    1    1024    1024
                            减数    51917364224
                            被减数    96993205379
                            差值    45075841155
假设另b=3,
10a次方    b次方    C(10,i)    系数*(10a)^j    *a^j    *b^i    1    3    积
9    1    10    10000000000    a^9    b^1    1    3    30000000000
8    2    45    4500000000    a^8    b^2    1    9    40500000000
7    3    120    1200000000    a^7    b^3    1    27    32400000000
6    4    210    210000000    a^6    b^4    1    81    17010000000
5    5    252    25200000    a^5    b^5    1    243    6123600000
4    6    210    2100000    a^4    b^6    1    729    1530900000
3    7    120    120000    a^3    b^7    1    2187    262440000
2    8    45    4500    a^2    b^8    1    6561    29524500
1    9    10    100    a^1    b^9    1    19683    1968300
0    10    1    1    a^0    b^10    1    59049    59049
                            减数    127858491849
                            被减数    96993205379
                            差值    -30865286470
差值已经是负数了,所以小数点后第一位小数是2,
当是2时,差值为:45075841155,再拉10位数,紧跟着还有0720000000,就成了450758411550720000000,这是个21位的大数,此时a=12,12的9次方,再扩大10^10倍作为试商,你能做到吗?也就是第三步就进行不下去了,如果得到了第三步结果,当第四步时,a是个三位数,它的9次方,再扩大10^10倍作为此时的试商,空拍此时大脑已经快爆炸了,如果毅力够坚强,这一步闯过去了,来到第五步,a是4位数,它9次方,扩大10^10倍作为试商(仅仅给你举了最大项,其实还有9项连加的),.......,如此反复进行,你能精确到小数点后几位数?恐怕不敢贪大。
    所以,原则上笔算开方是可行的,实际上,没有多大的进展。
#10
独木星空2022-08-27 20:44
10a次方    b次方    C(10,i)    系数*(10a)^j    *a^j    *b^i    12    6    积
9    1    10    10000000000    a^9    b^1    5159780352    6    3.09587E+20
8    2    45    4500000000    a^8    b^2    429981696    36    6.9657E+19
7    3    120    1200000000    a^7    b^3    35831808    216    9.2876E+18
6    4    210    210000000    a^6    b^4    2985984    1296    8.12665E+17
5    5    252    25200000    a^5    b^5    248832    7776    4.87599E+16
4    6    210    2100000    a^4    b^6    20736    46656    2.03166E+15
3    7    120    120000    a^3    b^7    1728    279936    5.80475E+13
2    8    45    4500    a^2    b^8    144    1679616    1.08839E+12
1    9    10    100    a^1    b^9    12    10077696    12093235200
0    10    1    1    a^0    b^10    1    60466176    60466176
                            减数    389394976646954000000
                            被减数    450758411550720000000
                            差值    61363434903766200000
非精确计算,因为电脑的有效位是15位数,已经是21位,借助电脑也无法进行下去。
10a次方    b次方    C(10,i)    系数*(10a)^j    *a^j    *b^i    12    7    积
9    1    10    10000000000    a^9    b^1    5159780352    7    3.61185E+20
8    2    45    4500000000    a^8    b^2    429981696    49    9.4811E+19
7    3    120    1200000000    a^7    b^3    35831808    343    1.47484E+19
6    4    210    210000000    a^6    b^4    2985984    2401    1.50556E+18
5    5    252    25200000    a^5    b^5    248832    16807    1.05389E+17
4    6    210    2100000    a^4    b^6    20736    117649    5.1231E+15
3    7    120    120000    a^3    b^7    1728    823543    1.7077E+14
2    8    45    4500    a^2    b^8    144    5764801    3.73559E+12
1    9    10    100    a^1    b^9    12    40353607    48424328400
0    10    1    1    a^0    b^10    1    282475249    282475249
                            减数    472360210833394000000
                            被减数    450758411550720000000
                            差值    -21601799282673500000
如果试商是7,则为负值。
#11
独木星空2022-08-27 20:45
实际上我们已经远离了轨道,在一个编程论坛讨论数学问题,有点偏离主题。
我其实对vb6一知半解。我一般是编写vfp程序获得数据。把笔算开平方发在了vfp编程论坛板块,20分的悬赏,可是快到期了,无一人问津,只好撤掉悬赏。
#12
独木星空2022-08-28 15:32
我们是不是可以先把多位数拆分,比如1234567890,表示成a=0,b=9,c=8,d=7,....,从个位倒着用字母表示,也可以统一用x1=0,x2=9,x3=8,....;用y1,y2,y3,....;来表示另一个整数,然后,就是它们分别相乘了,获得xi*yj个数据,用其角码表是位数(所以角码从0开始),这样角码之和就是位数(另角码之和加1确定),然后计算所有的角码之和相同的和,这样就完成笔算多位数相乘的汇总结果,最后把临近位再做处理(之和大于9的部分),最后输出一个处理好的数字文本(把各个位上的数字做倒排列而成)。
    只是一个初步设想,能不能实现是个问题。
#13
my23182022-08-28 17:02
主要涉及算法,把算法搞清楚,再编程不难
#14
独木星空2022-08-29 21:33
回复 13楼 my2318
这个问题从发出悬赏就没有人问津,我一个把多位数拆分成多个单元的想法也没人实现,所以,只能自己抽空解决了。自己买坑,自己跳。
#15
sych2022-08-30 08:46
SET TALK OFF
SET SAFETY OFF
clea
text
大数快速四则计算,(除法很耗时,最好转化为乘法再计算)
ll_Add     : 加 +
ll_Sub     : 减 -
ll_Mult    : 乘 *
ll_Div     : 除 /
ll_Mod     : 模 %/Mod()
ll_Less    : 小于 >
ll_IntSqrt : 平方根 SQRT()
ll_power   : 乘幂 ^/**
ll_pl      : 排列
ll_zh      : 组合


调用方法
? ll_mult("4", "4")  && 4x4
endtext

?
? "1000000位长度的 4 + 1000000位长度的 7 的运算结果:"
? "================================================"
m.a = Replicate("1244", 200)
m.b = Replicate("7457", 2)
m.sc = Seconds()
FOR i=1 TO 100
m.c = ll_add(m.a, m.b)
next
? "耗时 (秒)     :", Seconds() - m.sc
? "结果长度      :", Len(m.c)
? "左20位运算结果:", Left(m.c, 20)
?m.c
? "================================================"

*!* Function ll_add adds two integers, represented by strings m.s1 and m.s2
Function ll_add
    Lparameter m.s1, m.s2

    If Left(m.s1,1)="-"
        Return ll_sub(m.s2, Substr(m.s1,2))
    Endif

    If Left(m.s2,1)="-"
        Return ll_sub(m.s1, Substr(m.s2,2))
    Endif

    *!* Uncomment next rows if you want some additional data checking,
    *!* but this may dramaticaly reduce performance on large strings
    *!* local m.ln1, m.ln2, m.ln3, m.s3
    *!* if len(chrtran(m.s1, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s1"
    *!* return ""
    *!* endif

    *!* if len(chrtran(m.s2, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s2"
    *!* return ""
    *!* endif

    Local m.ln1, m.ln2, m.ln3, m.s3
    m.ln1=Len(m.s1)
    m.ln2=Len(m.s2)
    m.ln3 = Max(m.ln1, m.ln2)+1
    m.s1 = Padl(m.s1, m.ln3, "0")
    m.s2 = Padl(m.s2, m.ln3, "0")

    m.s3 = Repl("0", m.ln3)

    Local m.hhnd, m.ptr, m.st2, m.rez

    If !Pemstatus(_Screen,"ll_add",5) Or _Screen.ll_add=0
        Declare Integer HeapCreate In Win32Api Integer, Integer, Integer
        Declare Integer HeapAlloc In Win32Api Integer, Integer, Integer
        Declare RtlMoveMemory In Win32API Integer, String, Integer Cnt

        m.st2 = ;
            chr(0x55)+Chr(0x89)+Chr(0xE5)+Chr(0x57)+Chr(0x56)+Chr(0x50)+Chr(0x53)+Chr(0x51)+ ;
            chr(0x52)+Chr(0x8B)+Chr(0x75)+Chr(0x08)+Chr(0x8B)+Chr(0x5D)+Chr(0x0C)+Chr(0x8B)+ ;
            chr(0x4D)+Chr(0x10)+Chr(0x8B)+Chr(0x7D)+Chr(0x14)+Chr(0x8A)+Chr(0x04)+Chr(0x0E)+ ;
            chr(0x02)+Chr(0x04)+Chr(0x0B)+Chr(0x02)+Chr(0x04)+Chr(0x0F)+Chr(0x2C)+Chr(0x60)+ ;
            chr(0x3C)+Chr(0x39)+Chr(0x7E)+Chr(0x06)+Chr(0x2C)+Chr(0x0A)+Chr(0xFE)+Chr(0x44)+ ;
            chr(0x0F)+Chr(0xFF)+Chr(0x88)+Chr(0x04)+Chr(0x0F)+Chr(0x49)+Chr(0x75)+Chr(0xE5)+ ;
            chr(0x5A)+Chr(0x59)+Chr(0x5B)+Chr(0x58)+Chr(0x5E)+Chr(0x5F)+Chr(0x89)+Chr(0xEC)+ ;
            chr(0x5D)+Chr(0xC2)+Chr(0x10)+Chr(0x00)

        m.hhnd=HeapCreate(0x40000,1024,1024)
        m.ptr=HeapAlloc(m.hhnd,0,Len(m.st2)+16)
        RtlMoveMemory(m.ptr,m.st2,Len(m.st2))
        _Screen.AddProperty("ll_add",m.ptr)

    Endif

    Declare CallWindowProc In Win32API Integer, String, String, Integer, String @

    CallWindowProc(_Screen.ll_add, m.s1, m.s2, m.ln3-1, @m.s3)

    Return Chrtran(Ltrim(Chrtran(m.s3, "0", " ")), " ", "0")


    *!* Function ll_sub substracts integer, represented by strings m.s2 from the
    *!* integer, epresented by m.s1
Function ll_sub
    Lparameter m.s1, m.s2

    If Left(m.s2,1)="-"
        Return ll_add(m.s1, Substr(m.s2,2))
    Endif
    If Left(m.s1,1)="-"
        Return "-"+ll_add(Substr(m.s1,2), m.s2)
    Endif


    *!* Uncomment next rows if you want some additional data checking,
    *!* but this may dramaticaly reduce performance on large strings
    *!* local m.ln1, m.ln2, m.ln3, m.s3
    *!* if len(chrtran(m.s1, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s1"
    *!* return ""
    *!* endif

    *!* if len(chrtran(m.s2, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s2"
    *!* return ""
    *!* endif

    Local m.ln1, m.ln2, m.ln3, m.s3
    m.ln1=Len(m.s1)
    m.ln2=Len(m.s2)
    m.ln3 = Max(m.ln1, m.ln2)+1
    m.s1 = Padl(m.s1, m.ln3, "0")
    m.s2 = Padl(m.s2, m.ln3, "0")

    If m.s1 < m.s2
        Return "-"+ll_sub(m.s2, m.s1)
    Endif

    m.s3 = Repl("0", m.ln3)


    Local m.hhnd, m.ptr, m.st2, m.rez

    If !Pemstatus(_Screen,"ll_sub",5) Or _Screen.ll_sub=0
        Declare Integer HeapCreate In Win32Api Integer, Integer, Integer
        Declare Integer HeapAlloc In Win32Api Integer, Integer, Integer
        Declare RtlMoveMemory In Win32API Integer, String, Integer Cnt

        m.st2 = ;
            chr(0x55)+Chr(0x89)+Chr(0xE5)+Chr(0x57)+Chr(0x56)+Chr(0x50)+Chr(0x53)+Chr(0x51)+ ;
            chr(0x52)+Chr(0x8B)+Chr(0x75)+Chr(0x08)+Chr(0x8B)+Chr(0x5D)+Chr(0x0C)+Chr(0x8B)+ ;
            chr(0x4D)+Chr(0x10)+Chr(0x8B)+Chr(0x7D)+Chr(0x14)+Chr(0xBA)+Chr(0x00)+Chr(0x00)+ ;
            chr(0x00)+Chr(0x00)+Chr(0x8A)+Chr(0x04)+Chr(0x0E)+Chr(0x00)+Chr(0x14)+Chr(0x0B)+ ;
            chr(0x2A)+Chr(0x04)+Chr(0x0B)+Chr(0x7D)+Chr(0x06)+Chr(0xB2)+Chr(0x01)+Chr(0x04)+ ;
            chr(0x0A)+Chr(0xEB)+Chr(0x02)+Chr(0xB2)+Chr(0x00)+Chr(0x04)+Chr(0x30)+Chr(0x88)+ ;
            chr(0x04)+Chr(0x0F)+Chr(0x49)+Chr(0x75)+Chr(0xE5)+Chr(0x5A)+Chr(0x59)+Chr(0x5B)+ ;
            chr(0x58)+Chr(0x5E)+Chr(0x5F)+Chr(0x89)+Chr(0xEC)+Chr(0x5D)+Chr(0xC2)+Chr(0x10)+ ;
            chr(0x00)

        m.hhnd=HeapCreate(0x40000,1024,1024)
        m.ptr=HeapAlloc(m.hhnd,0,Len(m.st2)+16)
        RtlMoveMemory(m.ptr,m.st2,Len(m.st2))
        _Screen.AddProperty("ll_sub",m.ptr)

    Endif

    Declare CallWindowProc In Win32API Integer, String, String, Integer, String @

    CallWindowProc(_Screen.ll_sub, m.s1, m.s2, m.ln3-1, @m.s3)
    Return Chrtran(Ltrim(Chrtran(m.s3, "0", " ")), " ", "0")


    *!* Function ll_mult multiplies two integers, represented by strings m.s1 and m.s2
Function ll_mult
    Lparameter m.s1, m.s2

    Do Case
        Case Left(m.s1,1) = "-" And Left(m.s2,1) <> "-"
            Return "-" + ll_mult(Substr(m.s1,2), m.s2)
        Case Left(m.s1,1) <> "-" And Left(m.s2,1) = "-"
            Return "-" + ll_mult(m.s1, Substr(m.s2,2))
        Case Left(m.s1,1) = "-" And Left(m.s2,1) = "-"
            Return ll_mult(Substr(m.s1,2), Substr(m.s2,2))
    Endcase


    *!* Uncomment next rows if you want some additional data checking,
    *!* but this may dramaticaly reduce performance on large strings
    *!* local m.ln2, m.sm, m.i
    *!* if len(chrtran(m.s1, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s1"
    *!* return ""
    *!* endif

    *!* if len(chrtran(m.s2, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s2"
    *!* return ""
    *!* endif

    Local m.ln2, m.sm, m.i
    m.ln2 = Len(m.s2)

    m.sm = "0"

    For i = 1 To m.ln2
        m.sm = ll_add(m.sm, ll_mult1(m.s1, Int(Val(Substr(m.s2, m.ln2-i+1, 1)))) + Repl("0", i-1))
    Next

    Return m.sm



    *!* Function ll_mult1 multiplies integers, represented by strings m.s1 and one digit integer m.n2
    *!* Is used by function ll_mult
Function ll_mult1
    Lparameter m.s1, m.n2

    *!* Uncomment next rows if you want some additional data checking,
    *!* but this may dramaticaly reduce performance on large strings
    *!* if len(chrtran(m.s1, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s1"
    *!* return ""
    *!* endif

    Local m.ln1, m.s3
    m.ln1 = Len(m.s1)+1
    m.s1="0"+m.s1

    m.s3 = Repl("0", m.ln1)


    Local m.hhnd, m.ptr, m.st2, m.rez

    If !Pemstatus(_Screen,"ll_mult1",5) Or _Screen.ll_mult1=0
        Declare Integer HeapCreate In Win32Api Integer, Integer, Integer
        Declare Integer HeapAlloc In Win32Api Integer, Integer, Integer
        Declare RtlMoveMemory In Win32API Integer, String, Integer Cnt

        m.st2 = ;
            chr(0x55)+Chr(0x89)+Chr(0xE5)+Chr(0x57)+Chr(0x56)+Chr(0x50)+Chr(0x53)+Chr(0x51)+ ;
            chr(0x52)+Chr(0x8B)+Chr(0x75)+Chr(0x08)+Chr(0x8B)+Chr(0x5D)+Chr(0x0C)+Chr(0x8B)+ ;
            chr(0x4D)+Chr(0x10)+Chr(0x8B)+Chr(0x7D)+Chr(0x14)+Chr(0xBA)+Chr(0x0A)+Chr(0x00)+ ;
            chr(0x00)+Chr(0x00)+Chr(0x8A)+Chr(0x04)+Chr(0x0E)+Chr(0x2C)+Chr(0x30)+Chr(0xF6)+ ;
            chr(0xE3)+Chr(0xF6)+Chr(0xF2)+Chr(0x00)+Chr(0x24)+Chr(0x0F)+Chr(0x80)+Chr(0x3C)+ ;
            chr(0x0F)+Chr(0x39)+Chr(0x7E)+Chr(0x08)+Chr(0xFE)+Chr(0x44)+Chr(0x0F)+Chr(0xFF)+ ;
            chr(0x80)+Chr(0x2C)+Chr(0x0F)+Chr(0x0A)+Chr(0x00)+Chr(0x44)+Chr(0x0F)+Chr(0xFF)+ ;
            chr(0x49)+Chr(0x75)+Chr(0xDF)+Chr(0x5A)+Chr(0x59)+Chr(0x5B)+Chr(0x58)+Chr(0x5E)+ ;
            chr(0x5F)+Chr(0x89)+Chr(0xEC)+Chr(0x5D)+Chr(0xC2)+Chr(0x10)+Chr(0x00)

        m.hhnd=HeapCreate(0x40000,1024,1024)
        m.ptr=HeapAlloc(m.hhnd,0,Len(m.st2)+16)
        RtlMoveMemory(m.ptr,m.st2,Len(m.st2))
        _Screen.AddProperty("ll_mult1",m.ptr)

    Endif

    Declare CallWindowProc In Win32API Integer, String, Integer, Integer, String @

    CallWindowProc(_Screen.ll_mult1, m.s1, m.n2, m.ln1-1, @m.s3)
    Return Chrtran(Ltrim(Chrtran(m.s3, "0", " ")), " ", "0")
  *!* Function ll_div divides integer, represented by strings m.s1 by the
    *!* integer, epresented by m.s1. (int(m.s1/m.s2)). If parameter m.md is
    *!* passed by reference, mod(m.s1,m.s2) is returned in m.md
Function ll_div
    Lparameter m.s1, m.s2, m.md

    Do Case
        Case Left(m.s1,1) = "-" And Left(m.s2,1) <> "-"
            Return "-" + ll_div(Substr(m.s1,2), m.s2)
        Case Left(m.s1,1) <> "-" And Left(m.s2,1) = "-"
            Return "-" + ll_div(m.s1, Substr(m.s2,2))
        Case Left(m.s1,1) = "-" And Left(m.s2,1) = "-"
            Return ll_div(Substr(m.s1,2), Substr(m.s2,2))
    Endcase


    *!* Uncomment next rows if you want some additional data checking,
    *!* but this may dramaticaly reduce performance on large strings
    *!* local m.ln1, m.ln2, m.sm, m.i, m.ts1, m.ts1e,
    *!* if len(chrtran(m.s1, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s1"
    *!* return ""
    *!* endif

    *!* if len(chrtran(m.s2, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s2"
    *!* return ""
    *!* endif

    If ll_less(m.s1, m.s2)
        m.md = m.s1
        Return "0"
    Endif

    Local m.ln1, m.ln2, m.sm, m.i, m.ts1, m.ts1e,
    m.ln2 = Len(m.s2)
    m.sm = ""
    m.ts1 = Left(m.s1, m.ln2)
    m.ts1e = Substr(m.s1, m.ln2 + 1)
    m.ln1 = Len(m.ts1e)
    For m.i = 1 To m.ln1 +1
         = 0
        Do While !ll_less(m.ts1, m.s2)
            m.ts1 = ll_sub(m.ts1, m.s2)
             = + 1
        Enddo
        m.sm = m.sm + Allt(Str())
        m.ts1 = m.ts1 + Left(m.ts1e, 1)
        m.ts1e = Substr(m.ts1e, 2)
    Next

    m.sm = tr0(m.sm)
    m.md = m.ts1
    Return m.sm



    *!* Function ll_mod returns mod(m.s1, m.s2)
Function ll_mod
    Lparameter m.s1, m.s2

    Do Case
        Case Left(m.s1,1) = "-" And Left(m.s2,1) <> "-"
            Return ""
        Case Left(m.s1,1) <> "-" And Left(m.s2,1) = "-"
            Return ""
        Case Left(m.s1,1) = "-" And Left(m.s2,1) = "-"
            Return ""
    Endcase

    Local m.md
    ll_div(m.s1, m.s2, @m.md)
    Return m.md


    *!* Function ll_less compare two integers, represented by m.s1 and m.s2.
    *!* .t. is returned if m.s1 < m.s2
Function ll_less
    Lparameter m.s1, m.s2
    Do Case
        Case Left(m.s1,1) = "-" And Left(m.s2,1) <> "-"
            Return .T.
        Case Left(m.s1,1) <> "-" And Left(m.s2,1) = "-"
            Return .F.
        Case Left(m.s1,1) = "-" And Left(m.s2,1) = "-"
            Return ll_less(Substr(m.s2,2), Substr(m.s1,2))
    Endcase

    m.s1 = tr0(m.s1)
    m.s2 = tr0(m.s2)

    Return Len(m.s1) < Len(m.s2) Or (Len(m.s1) = Len(m.s2) And m.s1 < m.s2)

    *!* Function tr0 is used by function ll_less
Function tr0
    Lparameter m.s1
    Do While Left(m.s1, 1) = "0" And Len(m.s1) > 1
        m.s1 = Substr(m.s1, 2)
    Enddo
    Return m.s1


    *!* Funnction ll_intsqrt returns mod(m.s1, m.s2)
Function ll_intsqrt
    Lparameter m.s1

    *!* Uncomment next rows if you want some additional data checking,
    *!* but this may dramaticaly reduce performance on large strings
    *!* if len(chrtran(m.s1, "0123456789", "")) > 0
    *!* wait window "Long_ar: error in s1"
    *!* return ""
    *!* endif

    Local m.ln, m.chet, m.tln, m.sq, m.i, m.j, m.tsq, m.tkv, m.tnkv
    m.ln = Len(m.s1)
    If m.ln <= 16
        Return Allt(Str(Int(Sqrt(Val(m.s1)))))
    Endif
    m.chet = m.ln%2
    m.tln = m.ln - 16 + m.chet
    m.sq = Allt(Str(Int(Sqrt(Val(Left(m.s1, m.ln - m.tln))))))

    For m.i = 1 To m.tln/2
        m.tkv = Left(m.s1, m.ln - m.tln + m.i*2)
        For m.j = 9 To 0 Step -1
            m.tsq = m.sq+Allt(Str(m.j))
            m.tnkv = ll_mult(m.tsq, m.tsq)
            If ll_less(m.tnkv, m.tkv) Or m.tnkv == m.tkv
                Exit
            Endif
        Next
        m.sq = m.sq + Allt(Str(m.j))
    Next
    Return m.sq



Function ll_add_dec
    Lparameter m.s1, m.s2, m.dec
    Local m.pos1, m.pos2
    m.pos1 = Rat(".", m.s1)
    If m.pos1 = 0
        m.s1 = m.s1 + Repl("0", m.dec)
    Else
        m.s1 = Left(m.s1, m.pos1 - 1) + Padr(Substr(m.s1, m.pos1 + 1), m.dec, "0")
    Endif

    m.pos2 = Rat(".", m.s2)
    If m.pos2 = 0
        m.s2 = m.s2 + Repl("0", m.dec)
    Else
        m.s2 = Left(m.s2, m.pos2 - 1) + Padr(Substr(m.s2, m.pos2 + 1), m.dec, "0")
    Endif

    m.res = ll_add(m.s1, m.s2)
    If Len(m.res) > m.dec
        Return Left(m.res, Len(m.res) - m.dec) + "." + Right(m.res, m.dec)
    Else
        Return "0."+Padl(m.res, m.dec, "0")
    Endif


Function ll_power
    Lparameter m.s1, m.s2
    m.pow = m.s1
    For I = 1 To Val(m.s2) - 1
    m.pow = ll_Mult(m.pow, m.s1)
    Endfor
    Return m.pow



Function ll_pl
    Lparameter m.s1, m.s2
    m.pow = m.s1
    For I = 1 To Val(m.s2) - 1
    m.pow = ll_Mult(m.pow, LTRIM(STR(VAL(m.s1)-i)))
    Endfor
    Return m.pow


Function ll_zh
    Lparameter m.s1, m.s2
    Return ll_div(ll_pl(m.s1,m.s2),ll_pl(m.s2,m.s2))

#16
wp2319572022-08-30 15:28
回复 14楼 独木星空
我用PYTHON写出来了,不足50行代码
下面是测试结果
PS D:\wpp> & C:/Programs/Python/python.exe d:/wpp/sqrt.py
对1进行开平方,我的=1.0000   电脑的=1.0000
对2进行开平方,我的=1.4142   电脑的=1.4142
对3进行开平方,我的=1.7320   电脑的=1.7321
对4进行开平方,我的=2.0000   电脑的=2.0000
对5进行开平方,我的=2.2360   电脑的=2.2361
对6进行开平方,我的=2.4494   电脑的=2.4495
对7进行开平方,我的=2.6457   电脑的=2.6458
对8进行开平方,我的=2.8284   电脑的=2.8284
对9进行开平方,我的=3.0000   电脑的=3.0000

PS D:\wpp>
#17
独木星空2022-08-30 21:24
精英人才还是有的。不能局限于一种算法,要横向对比。
#18
吹水佬2022-08-31 08:08
程序代码:
FOR i=1 TO 10
    FOR j=1 TO 10 STEP 2
        ? ROUND(SQRT(i/j),2), ROUND(QSqrt(i/j),2)
    ENDFOR
ENDFOR

FUNCTION QSqrt(x as Single)
    LOCAL xf as Single, xi as Integer
    xf = 0.5*x
    xi = CTOBIN(BINTOC(x,"4FS"),"4RS")
    xi = 1597463007 - BITRSHIFT(xi,1)
    x  = CTOBIN(BINTOC(xi,"4RS"),"4NS")
    RETURN 1/(x*(1.5-xf*x*x))
ENDFUNC
#19
独木星空2022-08-31 12:58
各位大佬都给出了,我还没有去运用。
#20
shy120312022-09-17 21:48
1