注册 登录
编程论坛 VB6论坛

各位老师好!求助编辑一个大整数的快速乘除法可调用程序

ysr2857 发布于 2020-02-10 23:10, 28927 次点击
我用于判断和筛选10亿内的素数表的程序速度太慢,1亿内的需要3个小时,10亿内的更是24个小时没有结果,只好关闭了,已经是采用了快速判断法,但效果低,原因是不会大整数的快速乘除法程序,希望老师帮助。我仅会一点VB语句,希望是用VB编程的。
我的判断素数的程序,对单个整数几十位的可以迅速判断,素数表就不行了,只能到1亿,单个整数100位以上的也不行。希望老师指点,会快速乘法除法的原理的也请指导帮助!
谢谢!
   祝愿各位老师,新年快乐,阖家幸福安康,万事如意!

[此贴子已经被作者于2020-2-10 23:14编辑过]

401 回复
#302
ysr28572021-04-25 07:33
这个代码如下:
Private Sub Command1_Click()
Dim m, n
m = Trim(Text1): n = Trim(Text2)
ts = Timer
c = MbC4(Trim(m), Trim(n))
Text3 = c & "用时" & Timer - ts & "秒,有" & Len(c) & "位"
End Sub

Private Sub Command2_Click()
Text1 = ""
Text2 = ""
Text3 = ""

End Sub

Public Function MbC4(D1 As String, D2 As String) As String '快速乘法
        Dim l As Long, le As Long, le1 As Long, n As Long, r As Long, p As Long, q As Long, m As Byte
  Dim wr As Double, w1 As Double, wlr As Double, wl1 As Double, tr As Double, t1 As Double
  Dim pi As Double, t As Double, tr1 As Double
        
  
Dim xr() As Double, a As String
  a = Trim(D1)
  B = Trim(D2)
  
  X = Len(a) \ 5: Y = Len(B) \ 5
  a = String(Val(X * 5 + 5 - Len(a)), "0") & a
  B = String(Val(Y * 5 + 5 - Len(B)), "0") & B
  X = X + 1: Y = Y + 1
  sb1 = X + Y
  sb2 = Log(sb1) / Log(2)
  If InStr(sb2, ".") = 0 Then
  sb2 = sb2
  Else
  sb2 = Int(sb2) + 1
  End If
  sb = 2 ^ sb2
  a = String(Val(sb) * 5 - Len(a), "0") & a
  B = String(Val(sb) * 5 - Len(B), "0") & B
  
   ReDim x_(1 To sb): ReDim y_(1 To sb)
    For i1 = 1 To sb
    x_(i1) = Mid(a, (sb - i1 + 1) * 5 - 4, 5): y_(i1) = Mid(B, (sb - i1 + 1) * 5 - 4, 5)
    If Len(x_(i1)) < 5 Then
    x_(i1) = String(5 - Len(x_(i1)), "0") & x_(i1)
    ElseIf Len(y_(i1)) < 5 Then
    y_(i1) = String(5 - Len(y_(i1)), "0") & y_(i1)
    Else
    x_(i1) = x_(i1): y_(i1) = y_(i1)
    End If
   
      Next
      ReDim xr(0 To (Len(a) - 5) \ 5): ReDim yr(0 To (Len(B) - 5) \ 5): ReDim zr(0 To (Len(B) - 5) \ 5)
      
       If Len(a) = 5 Then
  xr(0) = a: yr(0) = B
  Else
    Dim I As Long, J As Long, mn As Long, lh As Long, k As Long
    '位序倒置
n = sb '求数组大小,其值必须是2的幂
lh = n / 2
    J = n / 2
    For I = 1 To n - 2


    Debug.Print I, J
    k = lh '下面是向右进位算法
Do
    If k > J Then Exit Do '高位是1吗
J = J - k '是的,高位置0
    k = k / 2 '准备次高位的权
Loop Until k = 0 '次高位的权若非0,则检查新的次高位
J = J + k '非则若最高位是0,则置1
   xr(I + 1) = x_(J + 1): yr(I + 1) = y_(J + 1)
    Next
    xr(0) = x_(1): xr(1) = x_(1 + sb / 2)
    yr(0) = y_(1): yr(1) = y_(1 + sb / 2)
  
     End If
  
  Dim xi(): Dim yi(): Dim zi()
  n = sb '求数组大小,其值必须是2的幂
m = 0
  l = 2
  pi = 3.14159265358979
  Do
  l = l + l
  m = m + 1
  Loop Until l > n
  n = l / 2
  ReDim xi(n - 1): ReDim yi(n - 1): ReDim zi(n - 1)

  l = 1
  Do
    le = 2 ^ l
    le1 = le / 2
    wr = 1
    wi = 0
    If l = 1 Then
    t = 0
    Else
    t = pi / le1
    End If
    w1r = Cos(t)
    w1i = -Sin(t)
    r = 0
  Do
    p = r
    Do
     q = p + le1
     
     tr = xr(q) * wr - xi(q) * wi
     ti = xr(q) * wi + xi(q) * wr
     tr1 = yr(q) * wr - yi(q) * wi
     ti1 = yr(q) * wi + yi(q) * wr
     
     
     xr(q) = xr(p) - tr
     xi(q) = xi(p) - ti
     xr(p) = xr(p) + tr
     xi(p) = xi(p) + ti
     
       yr(q) = yr(p) - tr1
      yi(q) = yi(p) - ti1
      yr(p) = yr(p) + tr1
      yi(p) = yi(p) + ti1
     xr(p) = Format(Val(xr(p)), "0.000000"): xi(p) = Format(Val(xi(p)), "0.000000")
     yr(p) = Format(Val(yr(p)), "0.000000"): yi(p) = Format(Val(yi(p)), "0.000000")
     
      p = p + le
  Loop Until p > n - 1


  wr2 = wr * w1r - wi * w1i
  wi2 = wr * w1i + wi * w1r
  wr = wr2
  wi = wi2
  r = r + 1
  Loop Until r > le1 - 1
  l = l + 1
  Loop Until l > m

  For I = 0 To n - 1 '仅输出模
   zr(I) = xr(I) * yr(I) - xi(I) * yi(I): zi(I) = xr(I) * yi(I) + xi(I) * yr(I)
    zr(I) = Format(Val(zr(I)), "0.000000"): zi(I) = Format(Val(zi(I)), "0.000000")
  

      's = s & "/" & zr(I)
      's1 = s1 & "/" & zi(I)
      Next
      
       J = sb
     
       ReDim x_(1 To sb): ReDim y_(1 To sb)
     For k = 1 To J
         n1 = n1 + 1
          ReDim Preserve x_(1 To n1)
        
         x_(n1) = zr(n1 - 1): y_(n1) = zi(n1 - 1)
         x_(n1) = Format(Val(x_(n1)), "0.000000"): y_(n1) = Format(Val(y_(n1)), "0.000000")
         
       Next
   
    '位序倒置
n = sb '求数组大小,其值必须是2的幂
lh = n / 2
    J = n / 2
   
    For I = 1 To n - 2


    Debug.Print I, J
    k = lh '下面是向右进位算法
Do
    If k > J Then Exit Do '高位是1吗
J = J - k '是的,高位置0
    k = k / 2 '准备次高位的权
Loop Until k = 0 '次高位的权若非0,则检查新的次高位
J = J + k '非则若最高位是0,则置1

xr(I + 1) = x_(J + 1): yr(I + 1) = y_(J + 1)
    'js = js & "/" & x_(J + 1)
    'js1 = js1 & "/" & y_(J + 1)
    Next
    'sx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & js
    'sy1 = "/" & y_(1) & "/" & y_(1 + sb / 2) & js1
   xr(0) = x_(1): xr(1) = x_(1 + sb / 2)
   yr(0) = y_(1): yr(1) = y_(1 + sb / 2)
   
   
   ns = Len(a) \ 5: Jn = ns
  
      
  

  ReDim zr(0 To ns - 1)

  m = 0
  l = 2
  pi = 3.14159265358979
  Do
  l = l + l
  m = m + 1
  Loop Until l > ns
  ns = l / 2
  ReDim xi(ns - 1): ReDim yi(ns - 1): ReDim zi(ns - 1)

  l = 1
  Do
    le = 2 ^ l
    le1 = le / 2
    wr = 1
    wi = 0
    If l = 1 Then
    t = 0
    Else
    t = -1 * pi / le1
    End If
    w1r = Cos(t)
    w1i = -Sin(t)
    r = 0
  Do
    p = r
    Do
     q = p + le1
     
     tr = xr(q) * wr - xi(q) * wi
     ti = xr(q) * wi + xi(q) * wr
     tr1 = yr(q) * wr - yi(q) * wi
     ti1 = yr(q) * wi + yi(q) * wr
     
     
     xr(q) = xr(p) - tr
     xi(q) = xi(p) - ti
     xr(p) = xr(p) + tr
     xi(p) = xi(p) + ti
     
       yr(q) = yr(p) - tr1
      yi(q) = yi(p) - ti1
      yr(p) = yr(p) + tr1
      yi(p) = yi(p) + ti1
     xr(p) = Format(Val(xr(p)), "0.000000"): xi(p) = Format(Val(xi(p)), "0.000000")
     yr(p) = Format(Val(yr(p)), "0.000000"): yi(p) = Format(Val(yi(p)), "0.000000")
      p = p + le
  Loop Until p > ns - 1


  wr2 = wr * w1r - wi * w1i
  wi2 = wr * w1i + wi * w1r
  wr = wr2
  wi = wi2
  r = r + 1
  Loop Until r > le1 - 1
  l = l + 1
  Loop Until l > m

  For I = 0 To ns - 1 '仅输出模
zr(I) = (xr(I) - yi(I)) / n
      zr(I) = Format(Val(zr(I) + 0.5), "0.000000")
     If InStr(zr(I), ".") = 0 Then
     s121 = zr(I)
     Else
     s121 = Left(zr(I), InStr(zr(I), ".") - 1)
      End If
      's0 = "/" & s121 & s0
      zr(I) = s121
      Next
      For i1 = 1 To Val(Jn - sb1 + 1)
      zr(sb1 + i1 - 2) = 0
      Next
      
     
     
      For i1 = 0 To n - 1
      If zr(i1) < 0 Then
      zr(i1) = "00000"
      ElseIf Len(zr(i1)) < 5 Then
      zr(i1) = String(5 - Len(zr(i1)), "0") & zr(i1)
      Else
      zr(i1) = zr(i1)
      End If
      
      's5 = s5 & "/" & zr(i1)
      
      If i1 = 0 Then
      
      s6 = Val(Left(zr(i1), Len(zr(i1)) - 5))
      If Len(s6) < 5 Then
      s6 = String(5 - Len(s6), "0") & s6
      Else
      s6 = s6
      End If
      s8 = Right(zr(i1), 5)
      ElseIf Val(zr(i1)) >= 0 Then
      s7 = Val(zr(i1)) + Val(s6)
    If Len(s7) = 5 Or Len(s7) = 10 Or Len(s7) = 15 Then
          s7 = s7
          Else
          s7 = String(20 - Len(s7), "0") & s7
         End If
      s10 = Right(s7, 5)
      s11 = s10 & s11
      If Len(s7) < 5 Then
      s7 = String(5 - Len(s7), "0") & s7
      ElseIf Len(s7) = 5 Then
      s6 = "00000"
      Else
      s7 = s7
      s6 = Val(Left(s7, Len(s7) - 5))
      End If
      Else
      s6 = s6
      End If
     
      Next
      s9 = s6 & s11 & s8
     
   
   s9 = qdqd0(Trim(s9))
   
     's2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
     
     's3 = nifft(Trim(sx1), Trim(sy1), Trim(sb1))
      MbC4 = s9
  End Function

  Private Function qdqd0(sa As String) As String
  a = sa
  Do While Left(a, 1) = "0"
  a = Mid(a, 2)
  Loop
  If a = "" Then
  a = 0
  Else
  a = a
  End If
  qdqd0 = a
  End Function


[此贴子已经被作者于2021-5-4 18:41编辑过]

#303
ysr28572021-04-25 07:38
7172463269826462171528525227724894034214868966993605795401948124722087997342143358371455108964150545128907248526343196455641573509751354673861557821110693231777877738015812129161714061189179959717148156972438006245711375491637996368054355662274712424986912135083307535204835752100527089372858343068979871404409740751212288162364580340051030336669437742592243358179513860552191185265379861524597999525415656854787911581643398207658315370562159727183489341082919000873799051151043947664730614606995331479395199806790880383623001985260201859351553733798110323146855143033755798433086479488024524618236189650830082641092858321608765095677671296332855383698658513841618432462514767301509015302731887426449020324508457305854743150812148135681998160759231340593224787524059384993567619253642859738374890522751502722301228640973352385535814528059287908278674678352643221455078097708537386230468632692143543786079089278143231331448551012324709811279702452779256184630920739523413422282624035439915227985252545794326379126775078358185074208637164548385049952343933304537250581118807518766053939393481540287533027802322405590412993878611099596612132868370166415773181601154351447449360821364030895301897439991811626252222800042408837799445748876986689983744267954539975623901497977921404672456088365607147517753334119523085306549029501450784349931681757118493080278423158884618389416751863515799501941931299333482860034175574234687366084034854559860406380515922622731215797937947749347523567616361602120568917837553302958455697473044355271553097193939898199130578212161450820530733402948944817740996785663578468527435799222211621687841330657355269886610809724657106599734412672509267528377383850891990213998928910925665771135271178329415173122279497587450094043452968217137897325537655382191951751305922520305745720481516125474084463651538358435467578314496534799610440729366870223201955669253868969728058316618723047893958806793103141691041934291198205584987981081000108093858653439624897454612814469707610638127291418381351191694294777021231948012520106211264528527924444201382244571278473214765325480705119868390993533790074524744095675902347116176374826615934187667836147801248099347800023505688743794273915955274979733822944679464000508774509390349906781765163794451106428726498478530824886867499104246201491752880954757001517163612506498931595524274363029567180050754501432532286684708062072343197640125970583368911454340495069475260464330960780880200756901690402890214648943068478380757589861100818684623184349329031152871503812892139965016318354450639572431318054475101906966356246728290357750255900892206636706659073423666601520176669794618490222246109251969096246673833325909200541908647265810778433581200166738963648865628467965987974276129559867820182461324727175812909248560556153989070551651206916397043015129112324174041078381598687340367330369743574483768123513914466078688385552657957466373141833312470005872038158158558758597782287039757518156507558332909095180665881503900399254393925538499082517233770693477475440628379280827399682320040292147212671478850267113144256467717832789836095684233795606474628605577407950893979220730884373604393712239399619598622515105407684769318956407495911888144725372198319167914080204643210431914238821762306355036590446232568753016880799686685880210761285646606345578580056778051890680006982633074396045998096007046814297317508472091232768681594848779768724106961419347315786049071217250606391912412090036387359478549697004116901877456389276560046168633296499987754935871886741805805544288336626689145248219392479520665544572592654825874224723479880277722687977622479652630381460400253566835128569128126839849213424501027798623052330552639340014466433204854284282451838267652596510117073421554349769115596747847222786403991672125861002797993917039353677197561761018603077826216853034619545722932609155001960887797757724784083641663152934067672560173435725465409431333528091135523120222385280011570777644633992350683777567415457830142061356335821132623807179012101446605207533723888496145283691343028263101524024846536249138277962355381236115191250993587394690915625304012223449766194430885987517644469628964169109557807580762078537823980480277465642584796467360214177043602577120889280685824649388496001273597116159134970313980353087497406685979214581267102484657541875734018573130363674965905476673163481843821632051283681039720334533765017564509447055586120874529359775805844927319441709905022001704116387838005555153895216897265575940773948153176057832585460429745756094209528141488349976396674145584278724158836079117395297220622272613076439797697250956341920663130800734933155473346047738298666918898902058007968877485494163402560976541434704853172824135465265265413974659965992895056898571176505487405592027170864616186946549268484945297743480501600120064292645208037740939399240094229556634953081272586550404921251625234389912469589310281012901392380576054483238327215960879621215969418846522922054542058918325244657436478923637305716604682937562502625439542890870560297001951641986789624288562889846686525163088338471193186909768839469313807434287938259075089209910815237602035006864287774116054689067777229371270478665958455578247242113942197143505270008270270882191459688500066171521085054637377654252805754437567172842547938504092900808035624181824913689212947749777436293373997711125153064037803130649030656558546371288595296468051919653790009777109517042131035126573157883183656149031966290078048334686709613718875861993309644523724063515318637150743743389819818443552464423324971361456328433637001544654164638134029593641252649445564245102383007994865579077339457095651502941609117808906309223556024161286929108818191092639537820354261080758077666630753705679538620750240666605592530730238594235539574877759961712126221403282110319210039096970244934331283753007521745745837118120875705449296773432071049524935985944109558437494014526628545805285283211428212254815968453350353270667791149002454020746551663288384513504477866563520997609007704638752734240019484187769074642477074635474178236636866384721352427137750376744613001123164665522329698946864898915127542184529485587658494587744364754108361832698602920926798129076766271689152063216892000068702714408279505019745577786412160670706124504985662713657321905320058533322793579237307804061839083228241436729193118794125128602094745055040576711788450457579614174565175802897167080710639994745840408397188506013885908234200079470657560761093726188202968121735561672223506544407698071001104638286697863716911974871887889137352956177408235640187026335370180204269652496414622509246371913138867876466852915702002493457796630152391077246573798902025599992921947798890245930826255604543179370599273579602413417025291509137312565324651045766230943157633671851484144506416775604281483649665758671646087878710299223648600430794245286634276337844861170064580136723171347269810295795858398334220900459465680922702870972535103576876292907307652387534960191148834056753451657660931145515183543034393594453522937133734797355509943645187648731036090794950906104283431878826206307827524070028872299576965917050394234259986403377998509485079981363227077920026415618622428351304948072774838856801910366262559417442075232876162498709886882802124652312784435273507112770600208831184523646975165214379848407565171174246809997646009632924501230290592771311174549485322280542389123380362520652882111312033936289163788141960823931696888562106170237706550474284332740770252213900167894107284777482550350071361367151033525557171242907760562805679088739980478417471947819864720913692627336875658905474566774039096016299963861473601740086381354257179117749979010998112356352808189165832640207384776942252523357810039236078254183515529059874835125061234394074924909132255049783257541224053548198808652934695191418942834042371211524505976359110862030354610440635466142233137032127828857341531945816347930334509783514826135049690966965590328180073893837602188523301252123322723686120745275718705335983789003879497358018233759586456552862045742698107466630548973174919196570904489890564814069316083928253565097210010972987364689613782060247756229844584102377898827698947656763349306029039082478169225459931807461582437866510644539950728909670405185406776395849139556079466224657039622466467248175545823623111884112843786943196766907877471459634386322517853379671635861176446902694845586618133960389483456792263969375098395117758301586552554735290557282182649471723233085316948575654535258764959248191371622912245057971788968465050758911262576841267180636859779757898070212042118711333384216610181492870803869468282666126519808348146096589922650048641772202198072403546045272458781263186975049222383319870833843327375945414614154247992477644715054102005628243992111786180131664024016803330080223139821644587273437441338849555910477687563186510842007994149483363916523106835536022015378348641756245301023218771922044525978889328011515196392351153367647898428790542145817468347061491199973362848006838675577998841359685950026995771734056969750046174178343024201957430428174909217623707800454587541547999372447814554325540261532995290859332208048663519065389569542084421397802194571699591730237799757313714472333153018836276577894871710374936427805210334149251476143194011904103580927705512657445792637448210801981406325898853914731016758315659836542449366051395779886791126380622850691083405899521557705689988227787187036384654263022977011149854400284754958678411636633870582670219621470547411288183081931679714837078992548282323330288773323468937974805019102283375562950349861921150037994035660525472554512367270458369512316693424357275110365137080817513123195148755802178179447803099975134439746839174283238011413458411062894320960126845861170742217107400439529873590483426646151584669746270815795201用时1.933594秒,有9775位(这也是该程序算的,速度有所提高,仍然不如前面的模仿手工计算的快速乘法,如何优化?)
#304
zxyysy2021-05-18 01:38
学习学习
#305
ysr28572021-07-01 23:02
'超大整数的加减乘除运算及x进制转换

Option Explicit

 Public Function IIf(ByVal blnExp, vtTrue, vtFalse)
     If blnExp Then
         IIf = vtTrue
     Else
         IIf = vtFalse
     End If
 End Function

 Public Function ChangeType(vtData, vtType)
     Dim ret
     Select Case vtType
     Case vbEmpty
     Case vbNull
         ret = Null
     Case vbInteger
         ret = ChangeType(vtData, vbDouble)
         If ret >= -32768 And ret <= 32767 Then
             ret = CInt(ret)
         Else
             ret = 0
         End If
     Case vbLong
         ret = ChangeType(vtData, vbDouble)
         If ret >= -2147483648 And ret <= 2147483647 Then
             ret = CLng(ret)
         Else
             ret = CLng(0)
         End If
     Case vbSingle
         If IsNumeric(vtData) Then
             ret = CSng(vtData)
         ElseIf VarType(vtData) = vbDecimal Then
             ret = CSng(vtData)
         Else
             ret = CSng(0)
         End If
     Case vbDouble
         If IsNumeric(vtData) Then
             ret = CDbl(vtData)
         ElseIf VarType(vtData) = vbDecimal Then
             ret = CDbl(vtData)
         Else
             ret = CDbl(0)
         End If
     Case vbCurrency
         ret = ChangeType(vtData, vbDouble)
         If ret >= -922337203685477.5808 And ret <= 922337203685477.5807 Then
             ret = CCur(ret)
         Else
             ret = CCur(0)
         End If
     Case vbDate
         If IsDate(vtData) Then
             ret = CDate(vtData)
         End If
     Case vbString
         If Not IsNull(vtData) Then
             ret = CStr(vtData)
         Else
             ret = Empty
         End If
     Case vbBoolean
         ret = ChangeType(vtData, vbDouble)
         ret = CBool(Not ret = 0)
     Case vbByte
         ret = ChangeType(vtData, vbDouble)
         If ret >= 0 And ret <= 255 Then
             ret = CByte(ret)
         Else
             ret = CByte(0)
         End If
     Case Else
         If VarType(vtData) = vbObject Then
             Set ret = vtData
         Else
             ret = vtData
         End If
     End Select
     ChangeType = ret
 End Function

 Public Function atos(vtData)
     atos = ChangeType(vtData, vbString)
 End Function

 Public Function atoi(vtData)
     atoi = ChangeType(vtData, vbInteger)
 End Function

 Public Function atol(vtData)
     atol = ChangeType(vtData, vbLong)
 End Function

 Public Function atof(vtData)
     atof = ChangeType(vtData, vbDouble)
 End Function

 Class ImplNumber
 Public Function MyFormat(ByVal n)
     Dim p, r, l, i
     p = atos(n)
     l = Len(p)
     ReDim r(l - 1)
     For i = 1 To l
         r(i - 1) = (Asc(Mid(p, i, 1)) And &HFF) - 48
         If r(i - 1) < 0 Or r(i - 1) > 10 Then
             Err.Raise vbObjectError + 1, "ImplNumber.Format", "第" & (i - 1) & "位字符(" & Chr(r(i - 1) + 48) & ")非数字"
         End if
     Next
     MyFormat = r
 End Function

 Public Function MyFix(ByVal n)
     Dim p
     p = atos(n)
     Do While Left(p, 1) = "0"
         p = Mid(p, 2)
     Loop
     If p = "" Then p = "0"
     MyFix = p
 End Function

 Private Function Compare(ByVal n1, ByVal n2)
     Dim p1, p2
     Dim l1, l2
     Dim i, i1, i2
     p1 = atos(n1)
     p2 = atos(n2)
     l1 = Len(p1)
     l2 = Len(p2)
     If l1 > l2 Then
         Compare = 1
     ElseIf l1 < l2 Then
         Compare = -1
     ElseIf p1 = p2 Then
         Compare = 0
     Else
         For i = 1 To l1 Step 8
             i1 = CLng(Mid(p1, i, 8))
             i2 = CLng(Mid(p2, i, 8))
             If i1 > i2 Then
                 Compare = 1
                 Exit For
             ElseIf i1 < i2 Then
                 Compare = -1
                 Exit For
             End If
         Next
     End If
 End Function

 Private Function MyNumber(ByVal l)
     Dim r, i
     ReDim r(l)
     For i = 0 To l
         r(i) = 0
     Next
     MyNumber = r
 End Function

 Private Function MyAdd(ByVal n1, ByVal n2)
     Dim p1, p2, p3
     Dim l1, l2, l3
     Dim i, t
     p1 = MyFormat(n1)
     p2 = MyFormat(n2)
     l1 = UBound(p1)
     l2 = UBound(p2)
     l3 = IIf(l1 > l2, l1, l2) + 1
     p3 = MyNumber(l3)
     t = 0
     For i = 0 To l3
         If l1 - i >= 0 Then t = t + p1(l1 - i)
         If l2 - i >= 0 Then t = t + p2(l2 - i)
         p3(l3 - i) = IIf(t > 9, t - 10, t)
         t = IIf(t > 9, 1, 0)
     Next
     MyAdd = MyFix(Join(p3, ""))
     Erase p1
     Erase p2
     Erase p3
 End Function

 Private Function MySubtract(ByVal n1, ByVal n2)
     Dim p1, p2, p3, sign
     Dim i, t, l1, l2, l3
     Select Case Compare(n1, n2)
     Case -1
         p1 = MyFormat(n2)
         p2 = MyFormat(n1)
         sign = "-"
     Case 0
         MySubtract = "0"
         Exit Function
     Case 1
         p1 = MyFormat(n1)
         p2 = MyFormat(n2)
     End Select
     l1 = UBound(p1)
     l2 = UBound(p2)
     l3 = l1
     p3 = MyNumber(l3)
     t = 0
     For i = 0 To l3
        If l1 - i >= 0 Then t = p1(l1 - i) - t
        If l2 - i >= 0 Then t = t - p2(l2 - i)
        p3(l3 - i) = IIf(t < 0, t + 10, t)
        t = IIf(t < 0, 1, 0)
     Next
     MySubtract = sign & MyFix(Join(p3, ""))
     Erase p1
     Erase p2
     Erase p3
 End Function

 '加法
Public Function Add(ByVal n1, ByVal n2)
     Dim s1, s2
     Dim p1, p2
     p1 = MyFix(n1)
     p2 = MyFix(n2)
     s1 = Left(p1, 1)
     s2 = Left(p2, 1)
     If s1 = "-" Then p1 = MyFix(Mid(p1, 2))
     If s2 = "-" Then p2 = MyFix(Mid(p2, 2))
     If s1 = "-" Then
         If s2 = "-" Then
             Add = "-" & MyAdd(p1, p2)
         Else
             Add = MySubstract(p2, p1)
         End If
     Else
         If s2 = "-" Then
             Add = MySubtract(p1, p2)
         Else
             Add = MyAdd(p1, p2)
         End If
     End If
 End Function

 '减法
Public Function Subtract(ByVal n1, ByVal n2)
     Dim s1, s2
     Dim p1, p2
     p1 = MyFix(n1)
     p2 = MyFix(n2)
     s1 = Left(p1, 1)
     s2 = Left(p2, 1)
     If s1 = "-" Then p1 = MyFix(Mid(p1, 2))
     If s2 = "-" Then p2 = MyFix(Mid(p2, 2))
     If s1 = "-" Then
         If s2 = "-" Then
             Subtract = MySubstract(p2, p1)
         Else
             Subtract = "-" & MyAdd(p1, p2)
         End If
     Else
         If s2 = "-" Then
             Subtract = MyAdd(p1, p2)
         Else
             Subtract = MySubtract(p1, p2)
         End If
     End If
 End Function

 Private Function MyMultiply(ByVal n1, ByVal n2)
     Dim p1, p2, p3, p4
     Dim l1, l2, l3
     Dim i, k, t
     If Compare(n1, n2) = 1 Then
         p1 = MyFormat(n2)
         p2 = MyFormat(n1)
     Else
         p1 = MyFormat(n1)
         p2 = MyFormat(n2)
     End If
     l1 = UBound(p1)
     l2 = UBound(p2)
     p4 = "0"
     For i = 0 To l1
         l3 = l2 + i + 1
         p3 = MyNumber(l3)
         t = 0
         For k = 0 To l2
             t = t + p1(l1 - i) * p2(l2 - k)
             p3(l3 - i - k) = IIf(t > 9, (t Mod 10), t)
             t = IIf(t > 9, t / 10, 0)
         Next
         If t > 0 Then
             p3(l3 - i - k) = t
         End If
         p4 = MyAdd(p4, MyFix(Join(p3, "")))
         Erase p3
     Next
     MyMultiply = p4
     Erase p1
     Erase p2
 End Function

 '乘法
Public Function Multiply(ByVal n1, ByVal n2)
     Dim s1, s2
     Dim p1, p2
     p1 = MyFix(n1)
     p2 = MyFix(n2)
     s1 = Left(p1, 1)
     s2 = Left(p2, 1)
     If s1 = "-" Then p1 = MyFix(Mid(p1, 2))
     If s2 = "-" Then p2 = MyFix(Mid(p2, 2))
     If p1 = "0" Or p2 = "0" Then
         Multiply = "0"
     ElseIf s1 = "-" Then
         If s2 = "-" Then
             Multiply = MyMultiply(p1, p2)
         Else
             Multiply = "-" & MyMultiply(p1, p2)
         End If
     Else
         If s2 = "-" Then
             Multiply = "-" & MyMultiply(p1, p2)
         Else
             Multiply = MyMultiply(p1, p2)
         End If
     End If
 End Function

 Private Function MyDiv(ByVal n1, ByVal n2)
     Dim p(1), n3, i
     n3 = MySubtract(n1, n2)
     i = 1
     Do While Compare(n3, n2) <> -1
         n3 = MySubtract(n3, n2)
         i = i + 1
     Loop
     p(0) = i
     p(1) = n3
     MyDiv = p
 End Function

 Private Function MyDivision(ByVal n1, ByVal n2, ByVal decimal, ByVal sign)
     Dim p1, p2, p3(1), p4, p5
     Dim i, cmp, l1, l2, lx
     If decimal > 0 Then
         p1 = n1 & String(decimal, "0")
     Else
         p1 = n1
     End If
     p2 = n2
     cmp = Compare(p1, p2)
     If cmp = -1 Then
         p3(0) = 0
         p3(1) = n1
         MyDivision = p3
         Exit Function
     End If
     If cmp = 0 Then
         If decimal > 0 Then
             p3(0) = sign & "0." & String(decimal - 1, "0") & 1
             p3(1) = n1
         Else
             p3(0) = sign & "1"
             p3(1) = 0
         End If
         MyDivision = p3
         Exit Function
     End If
     l1 = Len(p1)
     l2 = Len(p2)
     lx = Len(n1)
     p4 = Mid(p1, 1, l2)
     i = l2
     p3(0) = sign
     If decimal > 0 And i > lx Then
         p3(0) = p3(0) & "." & String(i - lx - 1, "0")
     End If
     Do While i <= l1
         If Compare(p4, p2) <> -1 Then
             p5 = MyDiv(p4, p2)
             p4 = p5(1)
             p3(0) = p3(0) & p5(0)
         ElseIf i = l1 Then
             If i = lx Then p3(1) = MyFix(p4)
             Exit Do
         Else
             If i = lx Then
                 p3(1) = MyFix(p4)
                 If decimal > 0 Then p3(0) = p3(0) & "."
             End If
             i = i + 1
             p4 = MyFix(p4 & Mid(p1, i, 1))
             If Compare(p4, p2) = -1 Then p3(0) = p3(0) & "0"
         End If
     Loop
     MyDivision = p3
 End Function

 '除法
'decimal = 小数点后的位数
'函数返回拥有两个元素的数组
'元素0 = 商
'元素1 = 余数
Public Function Division(ByVal n1, ByVal n2, ByVal decimal)
     Dim s1, s2
     Dim p1, p2
     p1 = MyFix(n1)
     p2 = MyFix(n2)
     s1 = Left(p1, 1)
     s2 = Left(p2, 1)
     If s1 = "-" Then p1 = MyFix(Mid(p1, 2))
     If s2 = "-" Then p2 = MyFix(Mid(p2, 2))
     If p1 = "0" Then
         Division = Array(0, 0)
     ElseIf p2 = "0" Then
         Err.Raise vbObjectError + 1, "ImplNumber.Division", "被零除"
     ElseIf s1 = "-" Then
         If s2 = "-" Then
             Division = MyDivision(p1, p2, decimal, "")
         Else
             Division = MyDivision(p1, p2, decimal, "-")
         End If
     Else
         If s2 = "-" Then
             Division = MyDivision(p1, p2, decimal, "-")
         Else
             Division = MyDivision(p1, p2, decimal, "")
         End If
     End If
 End Function

 '将一个10进制整数进行(2 - 36)进制的转换
Public Function BaseX(ByVal n, ByVal x)
     Dim s, i, p
     If x < 2 Then
         Err.Raise vbObjectError + 1, "ImplNumber.BaseX", "错误的进制"
     End If
     If Compare(n, "0") = 1 Then
         p = Division(n, x, 0)
         s = s & BaseX(p(0), x)
         i = CInt(p(1))
         If i < 10 Then
             s = s & i
         Else
             s = s & Chr(i + 55)
         End If
     End If
     BaseX = s
 End Function

 '将一个(2 - 36)进制的字符转换成10进制的整数
Public Function ConvertX(ByVal s, ByVal x)
     Dim i
     Dim n, p, t
     If x < 2 Then
         Err.Raise vbObjectError + 1, "ImplNumber.ConvertX", "错误的进制"
     End If
     n = 0
     p = 1
     For i = Len(s) To 1 Step -1
         t = Asc(Mid(s, i, 1)) And &HFF
         If t >= 48 And t <= 57 Then
             t = t - 48
         ElseIf t >= 65 And t < 55 + x And t <= 90 Then
             t = t - 55
         ElseIf t >= 97 And t < 87 + x And t <= 122 Then
             t = t - 87
         Else
             Err.Raise vbObjectError + 1, "ImplNumber.ConvertX", "错误的进制字符串"
         End If
         n = Add(n, Multiply(t, p))
         p = Multiply(p, x)
     Next
     ConvertX = n
 End Function
 End Class

 '范例
Dim num, i, x
 Set num = New ImplNumber
 WScript.Echo num.Add(784921795923989, 5215632421426)
 WScript.Echo num.Subtract(784921795923989, 5215632421426)
 WScript.Echo num.Multiply(784921795923989, 5215632421426)
 WScript.Echo Join(num.Division(784921795923989, 5215632421426, 12), " - ")
 For i = 2 To 36
     x = num.BaseX(784921795923989, i)
     WScript.Echo "Base" & i & "(" & num.ConvertX(x, i) & ") = " & x
 Next
 Set num = Nothing
#306
ysr28572021-07-01 23:04
这个全是在网上复制的,不知道能不能运行,谢谢各位老师的指导和帮助!
#307
xianfajushi2021-11-16 06:53
还在研究算法速度?不如去学快速算法,或许是个方向。
#308
ysr28572021-11-18 18:42
回复 307楼 xianfajushi
刚才看到回复迟了深表歉意,请谅解!

是的,程序运行速度一直是我的难题可能是到了VB程序设计的天花板了?咋回事呢?VB程序设计即使用了傅立叶快速变换的乘法程序速度也是不快,主要是VB程序设计有效数字仅仅15位,不能发挥傅立叶变换的作用,因为变换的时候一位数字变换后的数值的整数部分就有3位的时候,由于有效数字只有15位则最多能把4位或者5位的z数字当做一位来用,而利用模仿手工计算的则可以把8位的字符串当一位用,模仿手工的乘法比傅立叶变换的乘法速度还要快了。

可能其他语言的软件适合傅立叶快速变换的乘法程序,比如VC语言可能就行,以后想学习一下VC。
还有mathematica据说也是很快的可以计算大整数大数据的,好象也是基于VC的程序,我也不会也没有这个软件。

向老师学习!

[此贴子已经被作者于2021-11-18 18:56编辑过]

#309
xianfajushi2021-12-08 11:20
过谦了,看来真心下功夫研究这题,哪里搜的分治资料等!
灵感可遇而不可求,刚写了开任意方的代码完全来自灵感,有兴趣的话可看我CSDN博客,写好了就想起这题目来了;
不过想要告诉你的是一个经验,从蛋骗鸡程序设计里面看到的现象,运算符的使用影响速度,如使用>和>=运算符后面的速度比较慢,因此同理要注意到。
#310
ysr28572021-12-08 11:31
谢谢关注和指导!分治法的资料都是网上搜索的,有的网站打不开需要收费,有的是开放的,基本方法一般是开放的,代码就可能是会收费的,我的方法仅仅供参考不收费,哈哈!
您的经验和程序很好,我缺乏这个资料和技术,谢谢!
#311
ysr28572021-12-08 11:35
回复 309楼 xianfajushi
您的代码都是VC写的,看不懂,我需要学习,一点也不会VC的。
#312
xianfajushi2021-12-08 15:04
以下是引用ysr2857在2021-4-23 09:22:25的发言:

分治法程序原理,见如下截图:

这是2种分治法原理?挺有意思的,有可能会写一个的。
#313
xianfajushi2021-12-08 15:42
想知道Karatsuba如何计算123*321的步骤
#314
xianfajushi2021-12-08 18:25
想知道Karatsuba如何计算123*32的步骤
#315
ysr28572021-12-08 21:20
回复 314楼 xianfajushi
我弄的分治法不能提高速度反而减慢了速度,没有可以指教的,请看看283和285楼,高手的点拨!
#316
ysr28572021-12-08 21:38
回复 313楼 xianfajushi
公式是设abcd都是数字,ab*cd如何乘?乘法有3个a*c,  b*d,   (a+b)*(c+d)

2个减法:(a+b)*(c+d)-a*c-b*d.

错位相加: a*c 00+(a+b)*(c+d)-a*c-b*d  0  +b*d

位数多了就多分几个段,循环这个过程而已。

[此贴子已经被作者于2021-12-8 21:46编辑过]

#317
ysr28572021-12-08 21:42
回复 314楼 xianfajushi
实际可能是仅仅减少了一步乘法,而增加了两步减法,如果减法速度不快的话就得不偿失,很难提高速度的,我的感觉就是这样的,仅仅供参考,请多看看高手的指点!
#318
xianfajushi2021-12-16 10:28
研究想要达到多少位才满足?如果能提高运算速度又有什么利益?
#319
ysr28572021-12-17 14:59
回复 318楼 xianfajushi
谢谢您的关注和指导,我的最快速度是几个小时算出来2^n其中的n是几不记得了,是个70万位多一点的数,这个速度是不行的,想要找到巨大的素数和孪生素数对,这个速度不能破解世界纪录。

世界纪录最大的素数是第51个梅森素数,有3千万位。目前发现的最大的孪生素数对是约38万位。
#320
ysr28572021-12-17 15:21
回复 318楼 xianfajushi
想要破解世界纪录,几十万位,甚至几千万位的整数,其乘法除法都必须在1秒内算一步,甚至更快,在几十毫秒内完成,可能是普通电脑不行?
破解纪录一般都是分布程序,就是并行程序,是成千上万台电脑联网的。

我想用普通电脑,用特殊算法试试,但速度太慢了,不行,不能实现。(特殊算法就是指,仅仅算一步除法,进行初步判断,比如:一般人认为对于梅森数若指数p是4x+3型的奇数,指数p若是素数,且2p+1也是素数,则该梅森数可以被2p+1整除,若是不能整除呢?那就基本可以确定是素数了,这样的情况是很稀少的。比如99368963是个素数,2*99368963=198737927也是素数,2^99368963-1是否能被198737927整除呢?如果不能被整除,那就可能是素数,几乎是确定的。第51个梅森素数没有这个数大呢,如果这个数是素数就是第52个梅森素数。)

谢谢您的支持和指导!欢迎沟通和探讨!
#321
xianfajushi2021-12-17 15:39
美国一家基金会还专门设立了 10 万美元的奖金,这奖金是真的?
求最大质数这个有时间限制?如果没有时间限制,慢慢求就是何必追求速度?
#322
ysr28572021-12-18 02:19
回复 321楼 xianfajushi
要判定梅森素数,是用的卢卡斯莱默测试法,该法一般要算到第p-1项,一般是若第p-1项的余数为0则可以确定为素数,就是有p-1步除法,一年才3千多万秒,该值是99368963,就是9千多万,如果1秒算一步除法,那么要算3年,普通电脑行吗?速度低于这个行吗?再低了,怕是算到宇宙的年龄也算不完了,行吗?

所以,用这个法的话,普通电脑可能是无法达到的。

[此贴子已经被作者于2021-12-19 08:33编辑过]

#323
ysr28572021-12-18 02:29
回复 321楼 xianfajushi
奖金是真的,如果超过1亿位了奖金就是15万美元了。

从48~51个都是美国人发现的,如果是别国人先发现的,还给人家奖金吗?
这个道是不能确定的,美国人说话不能信任的,为啥都是美国人发现的,别国人没有参与还是搞鬼了?这个都不清楚,
总之,你就是找到了第52个梅森素数,也可能人家不承认不给奖金。

如果是真的有这个能力,那就是为国争光了!起码中国专家会给你验证结果,并给你个答复或者给你个荣誉奖!
#324
xianfajushi2021-12-19 08:19
那么,加法 减法 应该都是O(N)算法,那就是要研究除法和乘法速度是?
#325
ysr28572021-12-19 08:35
回复 324楼 xianfajushi
对,不过,加法减法也是要尽量采用快速的算法,比如把多位数字当一位来算就可以快了一点。
#326
xianfajushi2021-12-19 09:08
加法 减法 乘法好似可以分段,除法能分段?
#327
ysr28572021-12-19 10:45
回复 326楼 xianfajushi
理论上除法也可以分段的,只不过分段后速度不会提高还可能降低了,而且容易出错。分段试商的时候要采用特殊算法不能一个一个试,否则速度就降低了,还要注意补0,商的位数不够的高位补0,所以,容易出错还不容易提高速度。

[此贴子已经被作者于2021-12-19 10:46编辑过]

#328
xianfajushi2021-12-19 16:34
你目前加法 减法能运行多少位数?用什么容纳数据?
#329
ysr28572021-12-19 17:19
回复 328楼 xianfajushi
不用考虑容纳,数据类型设为string 型,一般内存足够大就行,输出的时候若用控件text那最多输出65535位,要想完整输出得选其他文本设备,比如电脑自带的笔记格式等。

我算的最大的数是70万位的,没有输出来,中间计算都没有显示内存溢出等情况,只是程序慢,算了几个小时。
#330
ysr28572021-12-19 17:26
回复 328楼 xianfajushi
内存足够大的话,几千万位都没问题,上亿的行不行不知道,这么大数据一般不必输出,仅仅知道个结果(比如是素数还是合数等),特殊数据可以选择有用的或者有意义的一段字符串输出来就行。

[此贴子已经被作者于2021-12-19 17:27编辑过]

#331
xianfajushi2021-12-24 16:28
再等等,等中国量子计算机出市,可能不用费心去设计什么分段计算,届时应该有大数类型数据可用。
#332
ysr28572021-12-25 09:20
回复 331楼 xianfajushi
对,想法挺好,谢谢您关注和支持!
#333
xianfajushi2022-01-23 21:41
18位9平方是多少?
#334
ysr28572022-01-24 06:26
回复 333楼 xianfajushi
是说18位数的9次方吧?
那是大约不超过162位的数,如:(10^18)^9=10^162,如果是18的9次方就是18^9=有12位,用时0秒198359290368.
如:111111111111111111^9=有154位,用时0秒2581174791713197158759458382697978670921557790920035506950175781746019441940253190894093043179241870194428679274110358164356051907208242669891444486819591.
999999999999999999^9=有162位,用时0秒999999999999999991000000000000000035999999999999999916000000000000000125999999999999999874000000000000000083999999999999999964000000000000000008999999999999999999.

[此贴子已经被作者于2022-1-24 06:37编辑过]

#335
xianfajushi2022-01-24 10:52
18位9的平方是多少?能列出分治算式看看?
WIN计算器只能看到32位有效数字,再大就是科学表示法了,因此要看到大位数的有效数字,必须另行设计.

[此贴子已经被作者于2022-1-24 15:46编辑过]

#336
xianfajushi2022-01-25 05:37
之上提问好似没什么反应
目前仅发现51个梅森素数,最大的是M82589933(即282589933-1),有24862048位。
就如所述:我想用普通电脑,用特殊算法试试,但速度太慢了,不行,不能实现。(特殊算法就是指,仅仅算一步除法,进行初步判断,比如:一般人认为对于梅森数若指数p是4x+3型的奇数,指数p若是素数,且2p+1也是素数,则该梅森数可以被2p+1整除,若是不能整除呢?那就基本可以确定是素数了,这样的情况是很稀少的。比如99368963是个素数,2*99368963=198737927也是素数,2^99368963-1是否能被198737927整除呢?如果不能被整除,那就可能是素数,几乎是确定的。第51个梅森素数没有这个数大呢,如果这个数是素数就是第52个梅森素数。)
家用普通电脑创建这样一个数组是否满足需求_int64 a[100000]{}
相信数值运算远比字符运算快得多得多多
这就是我的分治法,不同以往字符运算,与其在字符上绞尽脑汁,不如跳出字符,另寻新途。
只有本站会员才能查看附件,请 登录



[此贴子已经被作者于2022-1-25 05:44编辑过]

#337
ysr28572022-01-25 05:49
回复 336楼 xianfajushi
18位9的平方是36位:999999999999999999^2=有36位,用时0秒999999999999999998000000000000000001.
代码如下:(只发主程序)

Private Sub Command1_Click() '快速幂程序
Dim A, B
A = Text1: B = Text2
ts = Timer
If B = 1 Then
Text3 = A
ElseIf B = 0 Then
Text3 = 1
Else
a1 = A
Do While B > 1
s = Int(Log(B) / Log(2))
s1 = 0
Do While s1 < s
A = MbC(Trim(A), Trim(A))
s1 = s1 + 1
Loop
a2 = A
B = B - 2 ^ s
A = a1
If s2 > 0 Then
a3 = MbC(Trim(a3), Trim(a2))
Else
a3 = a2
End If
s2 = s2 + 1
Loop
If B = 1 Then
js3 = MbC(Trim(a3), Trim(a1))
Else
js3 = a3
End If
s3 = Len(js3)
Text3 = "有" & s3 & "位,用时" & Timer - ts & "秒" & js3
End If
End Sub
#338
ysr28572022-01-25 06:02
回复 335楼 xianfajushi
普通电脑好像仅仅有15位的有效数字,如果可以得到32位的有效数字,那采用快速傅里叶变换的乘法程序速度还是可以提高的,或者采用分治法也可以提高,分治法中可以把16位当作一位数字,那就快很多,比把8位或5位当作一位的快不少。
#339
xianfajushi2022-01-25 08:33
999,999,999,999,999,998,000,000,000,000,000,001
如果希冀32位有效数字当作一位运算的话,那只有继续等待了
C++里面有效数字是19位,好似VB里面没有这么大,当然是希望有效数字越大越好,如用目前条件来讨论的话那还可以继续,否则等待,若要用VB数据类型只能是讨论分治法.
只有本站会员才能查看附件,请 登录
这样有效数字能容纳2的62次方.
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2022-1-25 08:53编辑过]

#340
ysr28572022-01-26 15:49
回复 339楼 xianfajushi
有效数字是19位的话,还是不行提高不了多少,速度还是慢!只好等待,电脑硬件技术上来了,普通电脑也能有32位甚至更多的有效数字了,那就可以大大提高速度了。
#341
xianfajushi2022-02-16 21:20
#342
ysr28572022-02-17 08:51
回复 341楼 xianfajushi
很好!您用的是啥语言编程的?看不懂啊!
#343
xianfajushi2022-02-17 11:42
VB6数据类型Currency
数据类型Long
C++数据类型_int64
都是一样位数,可控制在18位进行运算
VB6没用到,用写出来你能用?
其实我的程序直接改为VB是很容易的,直接替换到数据类型即可,循环语句替换即可,程序内也没用到判断什么的,纯粹就是计算而已。
#344
ysr28572022-02-17 13:48
回复 343楼 xianfajushi
VB6数据类型Currency?这个不懂,有这个类型吗?
我不会,而和VB6是大不一样的。
#345
ysr28572022-02-17 15:30
回复 344楼 ysr2857
Private Sub Command1_Click()
Dim m, n
m = Trim(Text1): n = Trim(Text2)
ts = Timer
c = MbC4(Trim(m), Trim(n))
Text3 = c & "用时" & Timer - ts & "秒,有" & Len(c) & "位"
End Sub

Private Sub Command2_Click()
Text1 = ""
Text2 = ""
Text3 = ""

End Sub

Public Function MbC4(D1 As String, D2 As String) As String '快速乘法
        Dim l As Long, le As Long, le1 As Long, n As Long, r As Long, p As Long, q As Long, m As Byte
  Dim wr As Currency, w1 As Currency, wlr As Currency, wl1 As Currency, tr As Currency, t1 As Currency
  Dim pi As Currency, t As Currency, tr1 As Currency
        
  
Dim xr() As Currency, a As String
  a = Trim(D1)
  B = Trim(D2)
  
  X = Len(a) \ 6: Y = Len(B) \ 6
  a = String(Val(X * 6 + 6 - Len(a)), "0") & a
  B = String(Val(Y * 6 + 6 - Len(B)), "0") & B
  X = X + 1: Y = Y + 1
  sb1 = X + Y
  sb2 = Log(sb1) / Log(2)
  If InStr(sb2, ".") = 0 Then
  sb2 = sb2
  Else
  sb2 = Int(sb2) + 1
  End If
  sb = 2 ^ sb2
  a = String(Val(sb) * 6 - Len(a), "0") & a
  B = String(Val(sb) * 6 - Len(B), "0") & B
  
   ReDim x_(1 To sb): ReDim y_(1 To sb)
    For i1 = 1 To sb
    x_(i1) = Mid(a, (sb - i1 + 1) * 6 - 5, 6): y_(i1) = Mid(B, (sb - i1 + 1) * 6 - 5, 6)
    If Len(x_(i1)) < 6 Then
    x_(i1) = String(6 - Len(x_(i1)), "0") & x_(i1)
    ElseIf Len(y_(i1)) < 6 Then
    y_(i1) = String(6 - Len(y_(i1)), "0") & y_(i1)
    Else
    x_(i1) = x_(i1): y_(i1) = y_(i1)
    End If
   
      Next
      ReDim xr(0 To (Len(a) - 6) \ 6): ReDim yr(0 To (Len(B) - 6) \ 6): ReDim zr(0 To (Len(B) - 6) \ 6)
      
       If Len(a) = 6 Then
  xr(0) = a: yr(0) = B
  Else
    Dim I As Long, J As Long, mn As Long, lh As Long, k As Long
    '位序倒置
n = sb '求数组大小,其值必须是2的幂
lh = n / 2
    J = n / 2
    For I = 1 To n - 2


    Debug.Print I, J
    k = lh '下面是向右进位算法
Do
    If k > J Then Exit Do '高位是1吗
J = J - k '是的,高位置0
    k = k / 2 '准备次高位的权
Loop Until k = 0 '次高位的权若非0,则检查新的次高位
J = J + k '非则若最高位是0,则置1
   xr(I + 1) = x_(J + 1): yr(I + 1) = y_(J + 1)
    Next
    xr(0) = x_(1): xr(1) = x_(1 + sb / 2)
    yr(0) = y_(1): yr(1) = y_(1 + sb / 2)
  
     End If
  
  Dim xi() As Currency: Dim yi() As Currency: Dim zi() As Currency
  n = sb '求数组大小,其值必须是2的幂
m = 0
  l = 2
  pi = "3.141592653589793238"
  Do
  l = l + l
  m = m + 1
  Loop Until l > n
  n = l / 2
  ReDim xi(n - 1): ReDim yi(n - 1): ReDim zi(n - 1)

  l = 1
  Do
    le = 2 ^ l
    le1 = le / 2
    wr = 1
    wi = 0
    If l = 1 Then
    t = 0
    Else
    t = pi / le1
    End If
    w1r = Cos(t)
    w1i = -Sin(t)
    r = 0
  Do
    p = r
    Do
     q = p + le1
     
     tr = xr(q) * wr - xi(q) * wi
     ti = xr(q) * wi + xi(q) * wr
     tr1 = yr(q) * wr - yi(q) * wi
     ti1 = yr(q) * wi + yi(q) * wr
     
     
     xr(q) = xr(p) - tr
     xi(q) = xi(p) - ti
     xr(p) = xr(p) + tr
     xi(p) = xi(p) + ti
     
       yr(q) = yr(p) - tr1
      yi(q) = yi(p) - ti1
      yr(p) = yr(p) + tr1
      yi(p) = yi(p) + ti1
     xr(p) = Format(Val(xr(p)), "0.000000"): xi(p) = Format(Val(xi(p)), "0.000000")
     yr(p) = Format(Val(yr(p)), "0.000000"): yi(p) = Format(Val(yi(p)), "0.000000")
     
      p = p + le
  Loop Until p > n - 1


  wr2 = wr * w1r - wi * w1i
  wi2 = wr * w1i + wi * w1r
  wr = wr2
  wi = wi2
  r = r + 1
  Loop Until r > le1 - 1
  l = l + 1
  Loop Until l > m

  For I = 0 To n - 1 '仅输出模
   zr(I) = xr(I) * yr(I) - xi(I) * yi(I): zi(I) = xr(I) * yi(I) + xi(I) * yr(I)
    zr(I) = Format(Val(zr(I)), "0.000000"): zi(I) = Format(Val(zi(I)), "0.000000")
  

      's = s & "/" & zr(I)
      's1 = s1 & "/" & zi(I)
      Next
      
       J = sb
     
       ReDim x_(1 To sb): ReDim y_(1 To sb)
     For k = 1 To J
         n1 = n1 + 1
          ReDim Preserve x_(1 To n1)
        
         x_(n1) = zr(n1 - 1): y_(n1) = zi(n1 - 1)
         x_(n1) = Format(Val(x_(n1)), "0.000000"): y_(n1) = Format(Val(y_(n1)), "0.000000")
         
       Next
   
    '位序倒置
n = sb '求数组大小,其值必须是2的幂
lh = n / 2
    J = n / 2
   
    For I = 1 To n - 2


    Debug.Print I, J
    k = lh '下面是向右进位算法
Do
    If k > J Then Exit Do '高位是1吗
J = J - k '是的,高位置0
    k = k / 2 '准备次高位的权
Loop Until k = 0 '次高位的权若非0,则检查新的次高位
J = J + k '非则若最高位是0,则置1

xr(I + 1) = x_(J + 1): yr(I + 1) = y_(J + 1)
    'js = js & "/" & x_(J + 1)
    'js1 = js1 & "/" & y_(J + 1)
    Next
    'sx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & js
    'sy1 = "/" & y_(1) & "/" & y_(1 + sb / 2) & js1
   xr(0) = x_(1): xr(1) = x_(1 + sb / 2)
   yr(0) = y_(1): yr(1) = y_(1 + sb / 2)
   
   
   ns = Len(a) \ 6: Jn = ns
  
      
  

  ReDim zr(0 To ns - 1)

  m = 0
  l = 2
  pi = "3.141592653589793238"
  Do
  l = l + l
  m = m + 1
  Loop Until l > ns
  ns = l / 2
  ReDim xi(ns - 1): ReDim yi(ns - 1): ReDim zi(ns - 1)

  l = 1
  Do
    le = 2 ^ l
    le1 = le / 2
    wr = 1
    wi = 0
    If l = 1 Then
    t = 0
    Else
    t = -1 * pi / le1
    End If
    w1r = Cos(t)
    w1i = -Sin(t)
    r = 0
  Do
    p = r
    Do
     q = p + le1
     
     tr = xr(q) * wr - xi(q) * wi
     ti = xr(q) * wi + xi(q) * wr
     tr1 = yr(q) * wr - yi(q) * wi
     ti1 = yr(q) * wi + yi(q) * wr
     
     
     xr(q) = xr(p) - tr
     xi(q) = xi(p) - ti
     xr(p) = xr(p) + tr
     xi(p) = xi(p) + ti
     
       yr(q) = yr(p) - tr1
      yi(q) = yi(p) - ti1
      yr(p) = yr(p) + tr1
      yi(p) = yi(p) + ti1
     xr(p) = Format(Val(xr(p)), "0.000000"): xi(p) = Format(Val(xi(p)), "0.000000")
     yr(p) = Format(Val(yr(p)), "0.000000"): yi(p) = Format(Val(yi(p)), "0.000000")
      p = p + le
  Loop Until p > ns - 1


  wr2 = wr * w1r - wi * w1i
  wi2 = wr * w1i + wi * w1r
  wr = wr2
  wi = wi2
  r = r + 1
  Loop Until r > le1 - 1
  l = l + 1
  Loop Until l > m

  For I = 0 To ns - 1 '仅输出模
zr(I) = (xr(I) - yi(I)) / n
      zr(I) = Format(Val(zr(I) + 0.5), "0.000000")
     If InStr(zr(I), ".") = 0 Then
     s121 = zr(I)
     Else
     s121 = Left(zr(I), InStr(zr(I), ".") - 1)
      End If
      's0 = "/" & s121 & s0
      zr(I) = s121
      Next
      For i1 = 1 To Val(Jn - sb1 + 1)
      zr(sb1 + i1 - 2) = 0
      Next
      
     
     
      For i1 = 0 To n - 1
      If zr(i1) < 0 Then
      zr(i1) = "000000"
      ElseIf Len(zr(i1)) < 6 Then
      zr(i1) = String(6 - Len(zr(i1)), "0") & zr(i1)
      Else
      zr(i1) = zr(i1)
      End If
      
      's5 = s5 & "/" & zr(i1)
      
      If i1 = 0 Then
      
      s6 = Val(Left(zr(i1), Len(zr(i1)) - 6))
      If Len(s6) < 6 Then
      s6 = String(6 - Len(s6), "0") & s6
      Else
      s6 = s6
      End If
      s8 = Right(zr(i1), 6)
      ElseIf Val(zr(i1)) >= 0 Then
      s7 = Val(zr(i1)) + Val(s6)
    If Len(s7) = 6 Or Len(s7) = 12 Or Len(s7) = 18 Then
          s7 = s7
          Else
          s7 = String(24 - Len(s7), "0") & s7
         End If
      s10 = Right(s7, 6)
      s11 = s10 & s11
      If Len(s7) < 6 Then
      s7 = String(6 - Len(s7), "0") & s7
      ElseIf Len(s7) = 6 Then
      s6 = "000000"
      Else
      s7 = s7
      s6 = Val(Left(s7, Len(s7) - 6))
      End If
      Else
      s6 = s6
      End If
     
      Next
      s9 = s6 & s11 & s8
     
   
   s9 = qdqd0(Trim(s9))
   
     's2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
     
     's3 = nifft(Trim(sx1), Trim(sy1), Trim(sb1))
      MbC4 = s9
  End Function

  Private Function qdqd0(sa As String) As String
  a = sa
  Do While Left(a, 1) = "0"
  a = Mid(a, 2)
  Loop
  If a = "" Then
  a = 0
  Else
  a = a
  End If
  qdqd0 = a
  End Function

#346
ysr28572022-02-17 15:42
回复 345楼 ysr2857
   zr(I) = Val(xr(I) * yr(I) - xi(I) * yi(I)): zi(I) = Val(xr(I) * yi(I) + xi(I) * yr(I))

这一步溢出了
#347
xianfajushi2022-02-17 15:56
初稿未优化
只有本站会员才能查看附件,请 登录

a(8) = a(9)
只有本站会员才能查看附件,请 登录

aa(8) = 777777777777777777
Console.WriteLine(a(7) & a(8) & a(9))
只有本站会员才能查看附件,请 登录


[此贴子已经被作者于2022-2-17 16:24编辑过]

#348
ysr28572022-02-18 02:09
回复 347楼 xianfajushi
谢谢您!这是吧?
速度提高多少?
我不会 .
#349
xianfajushi2022-02-18 08:30
我这种程序不废话,处理器处理数据有多快就有多快,也就是处理器的速度,不受多余的操作影响数据处理速度,每单元数据位是字符串型的18倍,字符串型每处理一位数都要进行多次操作,而我这程序操作处理就按每语句一次算处理后就是18位数据,而且我这程序绝对不会发生数据溢出错误问题。

[此贴子已经被作者于2022-2-18 12:54编辑过]

#350
xianfajushi2022-02-18 10:52
不会其他语言没多大关系,关键是充分理解这种分治运算原理,明白了原理可以用任何语言写出来。
#351
ysr28572022-02-19 09:34
回复 350楼 xianfajushi
不懂原理,能编个大整数的快速乘法程序吗?看一下1秒内能算多少位的乘法?几千万位的一步乘法如果能在1秒内完成,那就好了,可以用于破解世界纪录了。

谢谢您关注和指导!
123456789