| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2514 人关注过本帖
标题:再次请教精度问题(继4月18日《请教筛选平方数》之续)
只看楼主 加入收藏
eepcvfp
Rank: 2
等 级:论坛游民
帖 子:171
专家分:19
注 册:2013-8-12
收藏
得分:0 
回复 10楼 井绳
学习了,留个脚印。
2018-04-22 00:35
红星二锅头
Rank: 8Rank: 8
等 级:贵宾
威 望:46
帖 子:491
专家分:754
注 册:2016-8-25
收藏
得分:0 
Clear
*!*    大数整数四则运算算法:
Local m.a, m.b, m.c
? "1. 大整数的加、减、乘、除、求根、取模的测试:"
m.a = Replicate("7", 100)
m.b = Replicate("4", 100)
?
? "100个7 + 100个4 = " + ll_Add(m.a, m.b)
?
? "100个7 - 100个4 = " + ll_Sub(m.a, m.b)
?
? "100个7 x 100个4 = " + ll_Mult(m.a, m.b)
?
? "100个7 / 100个4 = " + ll_Div(m.a, m.b)
?
? "100个7 % 100个4 = " + ll_Mod(m.a, m.b)
?
? "SQRT(100个7) = " + ll_IntSqrt(m.a)
?
m.a = "9854422144556622455625"
m.b = "56254455224444554"  && 175175.85238785721761703231817399
? "9854422144556622455625 / 56254455224444554 = " + ll_Div(m.a, m.b)
?
? "2. 大整有理数加法的测试:"
m.a = "2222222222.2222222222"
m.b = "3333333333.3333333333"
? "2222222222.2222222222 + 3333333333.3333333333 = " + ll_Add_Dec(m.a, m.b, 10)
?
? "3. 超大数乘法的速度测试:"
m.a = Replicate("4", 1000000)
m.b = Replicate("7", 1000000)
m.sc = Seconds()
m.c = ll_Add(m.a, m.b)
? "1000000个4 + 1000000个7 = 前 10个数是:" + Left(m.c, 10) + ",后10个数是:" + Right(m.c, 10)
? "用时:"+ Transform(Seconds() - m.sc) + "秒"
?
m.a = Replicate("4", 10000)
m.b = Replicate("7", 10000)
m.sc = Seconds()
m.c = ll_Mult(m.a, m.b)
? "10000个4 x 10000个7 = 前 10个数是:" + Left(m.c, 10) + ",后10个数是:" + Right(m.c, 10)
? "用时:"+ Transform(Seconds() - m.sc) + "秒"
? "Finish......"




*!*    ******************************************
*!*     能:大数整数加法函数。
*!*    函数名:ll_Add(m.s1, m.s2)
*!*    返回值:字符型,两数之和。Int(m.s1 + m.s2)
*!*     数:[m.s1, m.s2] : 字符型,加数,被加数
*!*     例:? ll_Add("11111111", "22222222")
*!*    ******************************************
Function ll_Add(m.s1 As Character, m.s2 As Character)
    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

    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 = Replicate("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")
Endfunc


*!*    ******************************************
*!*     能:大数整数减法函数。
*!*    函数名:ll_Sub(m.s1, m.s2)
*!*    返回值:字符型,两数之差。Int(m.s1, m.s2)
*!*     数:[m.s1, m.s2] : 字符型,减数,被减数
*!*     例:? ll_Sub("333333333", "2222222222")
*!*    ******************************************
Function ll_Sub(m.s1 As Character, m.s2 As Character)
    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

    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 = Replicate("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")
Endfunc


*!* Function ll_mult multiplies two integers, represented by strings m.s1 and m.s2
*!*    ******************************************
*!*     能:大数乘法函数。
*!*    函数名:ll_Mult(m.s1, m.s2)
*!*    返回值:字符型,两数之积。Int(m.s1 * m.s2)
*!*     数:[m.s1, m.s2] : 字符型,乘数,被乘数
*!*     例:? ll_Mult("33333333", "22222222")
*!*    ******************************************
Function ll_Mult(m.s1 As Character, m.s2 As Character)
    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

    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)))) + Replicate("0", i-1))
    Next

    Return m.sm
Endfunc


*!* Function ll_mult1 multiplies integers, represented by strings m.s1 and one digit integer m.n2
*!* Is used by function ll_mult
*!*    ******************************************
*!*     能:大数乘法函数 ll_Mult 子函数。
*!*    函数名:ll_Mult1(m.s1, m.s2)
*!*    返回值:字符型,两数之积。
*!*     数:[m.s1, m.s2] : 字符型,乘数,被乘数
*!*     例:? ll_Mult1("33333333", "22222222")
*!*    ******************************************
Function ll_Mult1(m.s1, m.n2)
    Local m.ln1, m.s3
    m.ln1 = Len(m.s1)+1
    m.s1="0"+m.s1

    m.s3 = Replicate("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")
Endfunc


*!*    ******************************************
*!*     能:大数整数位除法函数。
*!*    函数名:ll_Div(m.s1, m.s2)
*!*    返回值:字符型,两数之和。Int(m.s1/m.s2))
*!*     数:[m.s1, m.s2] : 字符型,除数,被除数
*!*          [m.dec] : 保留的小数位
*!*     例:? ll_Div("3333333333", "2222222222")
*!*    ******************************************
Function ll_Div(m.s1 As Character, m.s2 As Character, m.md As Integer)
*!*    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

    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
Endfunc


*!*    ******************************************
*!*     能:大数模数函数 ll_Mult 子函数。
*!*    函数名:ll_Mult1(m.s1, m.s2)
*!*    返回值:字符型,两数之积。Mod(m.s1, m.s2)
*!*     数:[m.s1, m.s2] : 字符型,乘数,被乘数
*!*     例:? ll_Mod("6666666666", "5555555555")
*!*    ******************************************
Function ll_Mod(m.s1 As Character, m.s2 As Character)
    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
Endfunc


*!*    ******************************************
*!*     能:大数整数比较函数。
*!*    函数名:ll_Less(m.s1, m.s2)
*!*    返回值:逻辑型,两数大小比较。
*!*     数:[m.s1, m.s2] : 字符型,if m.s1 < m.s2,返回 : T.
*!*     例:? ll_Less("11111111", "22222222")
*!*    ******************************************
Function ll_Less(m.s1 As Character, m.s2 As Character)
    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)
Endfunc


*!*    ******************************************
*!*     能:ll_Less 函数调用的子函数。
*!*    函数名:tr0(m.s1)
*!*    ******************************************
Function tr0(m.s1 As Character)
    Do While Left(m.s1, 1) = "0" And Len(m.s1) > 1
        m.s1 = Substr(m.s1, 2)
    Enddo
    Return m.s1
Endfunc


*!*    ******************************************
*!*     能:大数整数平方根函数。
*!*    函数名:ll_IntSqrt(m.s1)
*!*    返回值:字符型,求根。mod(m.s1, m.s2)
*!*     数:[m.s1] : 字符型
*!*     例:? ll_IntSqrt("44444444444444")
*!*    ******************************************
Function ll_IntSqrt(m.s1 As Character)
    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
Endfunc


*!*    ******************************************
*!*     能:大数小数位加法函数。
*!*    函数名:ll_Add(m.s1, m.s2, m.dec)
*!*    返回值:字符型,两数之和。m.s1 + m.s2
*!*     数:[m.s1, m.s2] : 字符型,加数,被加数
*!*          [m.dec] : 保留的小数位
*!*     例:? ll_Add_Dec("3333333333.3333333333", "2222222222.2222222222", 10)
*!*    ******************************************
*!*    Function ll_Add_Dec(m.s1 As Character, m.s2 As Character, m.dec As Integer)
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

团队红星二锅头,队长王猛,领队李冲,顾问杨伟,副队张挺,外联马彪,内勤韩秀,人事顾闯,财务赵魁,后勤周强
2018-04-22 07:36
schtg
Rank: 12Rank: 12Rank: 12
来 自:Usa
等 级:贵宾
威 望:67
帖 子:1732
专家分:3329
注 册:2012-2-29
收藏
得分:0 
学习啦,谢谢!
2018-04-22 08:39
快速回复:再次请教精度问题(继4月18日《请教筛选平方数》之续)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022310 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved