注册 登录
编程论坛 VB6论坛

这个倒序和蝶形算法vb程序如何运行?

ysr2857 发布于 2020-12-18 20:22, 9923 次点击
Sub 倒序(X_() As Double)
Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, k As Long
'位序倒置
n = UBound(X_) '求数组大小,其值必须是2的幂
lh = n / 2
j = n / 2
For i = 1 To n - 2
If i < j Then '倒序
t = X_(j)
X_(j) = X_(i)
X_(i) = t
End If

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
Next

End Sub

蝶形算法代码
Sub 蝶形算法(xr() As Double)
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
Dim xi()
n = UBound(xr) '求数组大小,其值必须是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)

l = 1
Do
  le = 2 ^ l
  le1 = le / 2
  wr = 1
  wi = 0
  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
   
   xr(q) = xr(p) - tr
   xi(q) = xi(p) - ti
   xr(p) = xr(p) + tr
   xi(p) = xi(p) + ti
   
   p = p + le
Loop Until p > n - 1

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

For i = 0 To n - 1 '仅输出模
   xr(i) = Sqr(xr(i) ^ 2 + xi(i) ^ 2)
   Next
   
End Sub


检验的时候可以这样:
Sub 检验()
Dim y(63) As Double
  For i = 0 To 64
  y(i) = Sin(2 * 3.1415926 * i / 16)
  Next
  倒序 y()
  蝶形算法 y()
  '现在结果在y()中
  

End Sub
89 回复
#52
ysr28572021-03-14 14:06
VC版大数乘法程序(迭代型),不知道能不能运行?(我不懂VC程序,希望老师帮忙翻译成VB程序试试,谢谢!)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <math.h>
#include <conio.h>
#define N 150010
const double pi = 3.141592653;
char s1[N>>1], s2[N>>1];
double rea[N], ina[N], reb[N], inb[N];
int ans[N>>1];
 
void Swap(double *x, double *y)
{
    double t = *x;
    *x = *y;
    *y = t;
}
 
int Rev(int x, int len)
{
    int ans = 0;
    int i;
    for(i = 0; i < len; i++){
        ans <<= 1;
        ans |= (x & 1);
        x >>= 1;
    }
    return ans;
}
 
void FFT(double *reA, double *inA, int n, bool flag)
{
    int s;
    double lgn = log((double)n) / log((double)2);
    int i;
    for(i = 0; i < n; i++){
        int j = Rev(i, lgn);
        if(j > i){
            Swap(&reA[i], &reA[j]);
            Swap(&inA[i], &inA[j]);
        }
    }
    for(s = 1; s <= lgn; s++){
        int m = (1<<s);
        double reWm = cos(2*pi/m), inWm = sin(2*pi/m);
        if(flag) inWm = -inWm;
        int k;
        for(k = 0; k < n; k += m){
            double reW = 1.0, inW = 0.0;
            int j;
            for(j = 0; j < m / 2; j++){
                int tag = k+j+m/2;
                double reT = reW * reA[tag] - inW * inA[tag];
                double inT = reW * inA[tag] + inW * reA[tag];
                double reU = reA[k+j], inU = inA[k+j];
                reA[k+j] = reU + reT;
                inA[k+j] = inU + inT;
                reA[tag] = reU - reT;
                inA[tag] = inU - inT;
                double rew_t = reW * reWm - inW * inWm;
                double inw_t = reW * inWm + inW * reWm;
                reW = rew_t;
                inW = inw_t;
            }
        }
    }
    if(flag){
        for(i = 0; i < n; i++){
            reA[i] /= n;
            inA[i] /= n;
        }
    }
}
 int main()
{
#if 0
    freopen("in.txt","r",stdin);
#endif
    while(~scanf("%s%s", s1, s2)){
        memset(ans, 0 , sizeof(ans));
        memset(rea, 0 , sizeof(rea));
        memset(ina, 0 , sizeof(ina));
        memset(reb, 0 , sizeof(reb));
        memset(inb, 0 , sizeof(inb));
        int i, lent, len = 1, len1, len2;
        len1 = strlen(s1);
        len2 = strlen(s2);
        lent = (len1 > len2 ? len1 : len2);
        while(len < lent) len <<= 1;
        len <<= 1;
        for(i = 0; i < len; i++){
            if(i < len1) rea[i] = (double)s1[len1-i-1] - '0';
            if(i < len2) reb[i] = (double)s2[len2-i-1] - '0';
            ina[i] = inb[i] = 0.0;
        }
        FFT(rea, ina, len, 0);
        FFT(reb, inb, len, 0);
        for(i = 0; i < len; i++){
            double rec = rea[i] * reb[i] - ina[i] * inb[i];
            double inc = rea[i] * inb[i] + ina[i] * reb[i];
            rea[i] = rec; ina[i] = inc;
        }
        FFT(rea, ina, len, 1);
        for(i = 0; i < len; i++)
            ans[i] = (int)(rea[i] + 0.4);
        for(i = 0; i < len; i++){
            ans[i+1] += ans[i] / 10;
            ans[i] %= 10;
        }
        int len_ans = len1 + len2 + 2;
        while(ans[len_ans] == 0 && len_ans > 0) len_ans--;
        for(i = len_ans; i >= 0; i--)
            printf("%d", ans[i]);
        printf("\n");
    }
    return 0;
}
#53
abc2383612021-03-15 11:00
#54
ysr28572021-03-15 11:46
回复 53楼 abc238361
谢谢关注和沟通!我有模仿手工计算的大整数的乘法程序,是可调用程序,结果准确可靠,就是速度慢,但几百位以内的没问题,可以快速算出来,再大的就慢了。代码再重发如下:
乘法和除法(仅仅计算整数)也发一下,速度太慢仅做参考!
 乘法程序:
Public Function MbC(D1 As String, D2 As String) As String '乘法
Dim x, Y '两数长度
x = Len(D1): Y = Len(D2)
 Dim a() As Integer
 ReDim a(1 To x + Y, 1 To Y)
 Dim I, J, C1, C2, CJ, JW
 For J = Y To 1 Step -1 'D2
 JW = 0 '进位清0
 C2 = Mid$(D2, J, 1) '每位数
For I = x To 1 Step -1 'D1
   C1 = Mid$(D1, I, 1) '每位数
  CJ = C1 * C2 + JW '计算乘积
  c = I + J: r = Y + 1 - J
   a(c, r) = CJ Mod 10 '本位
  JW = CJ \ 10 '进位
Next
 a(c - 1, r) = JW
 Next
 Dim b() As Integer
 ReDim b(1 To x + Y)
 JW = 0
 For I = x + Y To 1 Step -1
 Bit = JW
 For J = 1 To Y
   Bit = Bit + a(I, J)
 Next
 b(I) = Bit Mod 10
 JW = Bit \ 10
 Next
 If b(1) > 0 Then
 MbC = MbC & b(1)
 Else
 MbC = MbC
 End If
 For I = 2 To x + Y
 MbC = MbC & b(I)
 Next
 End Function

除法程序:(此程序只用于其中的除数小于8位的)(注意:输出的“/”号后面的是余数)
Public Function MCC(D1 As String, D2 As String) As String ';除数少于8位的除法
If Len(D1) < Len(D2) Then
    MCC = "0" & "/" & D1
    Else
    If Len(D1) < 9 Then
     MCC = Val(D1) \ Val(D2) & "/" & Val(D1) - (Val(D1) \ Val(D2)) * Val(D2)
      If Mid(MCC, InStr(MCC, "/") + 1) = 0 Then
   MCC = Left(MCC, InStr(MCC, "/") - 1)
 Else
 MCC = MCC
 End If
   
     Else
   
    Dim x ';fen duan changdu
    x = Len(D1)
   
      
   
      Dim a() As String
       ReDim a(1 To x)  ';定义数组的储存空间
      For I = 1 To x Step 1  ';把被除数各位放在a()中
       a(I) = Mid(D1, I, 1)
         
      
        Next I
       Dim b() As String
       JW = 0
      ReDim b(1 To x)
      For J = 1 To x Step 1
     b(J) = Val(JW & a(J)) \ Val(D2)
       JW = Val(JW & a(J)) - Val(b(J)) * Val(D2)
        Next J
        For r = 1 To x
        If JW = 0 Then
           MCC = MCC & b(r)
           Else
           CJ = CJ & b(r)
           MCC = CJ & "/" & JW
      
     End If
   
     For I = 1 To Len(MCC)
    If Not Mid(MCC, I, 1) = "0" Then
        Exit For
    End If
 Next
 strtmp = Mid(MCC, I)
 If Len(strtmp) = 0 Then
 MCC = "0"
 Else
 MCC = strtmp
 End If
   
    Next
   
    End If
      
      End If
   
 End Function

除法程序:(用于除数多于8位的)(注意:输出的“/”号后面的是余数)
Public Function MCC1(D1 As String, D2 As String) As String ';大整数的除法
Dim ss
 ss = MBJC(D1, D2)
 If ss = -1 Then
 MCC1 = "0" & "/" & D1
   Else
   If ss = 0 Then
    MCC1 = 1
    Else
    If Len(D1) = Len(D2) Then
      s = Val(Left(D1, 1)) \ Val(Left(D2, 1))

 Do While MBJC(MbC(Trim(s), Trim(D2)), D1) = 1
   s = s - 1
   Loop
   If MBJC(MbC(Trim(s), Trim(D2)), D1) = 0 Then
    MCC1 = s
    Else
    MCC1 = s & "/" & MPC(Trim(D1), MbC(Trim(s), Trim(D2)))

 End If
     Else
     If Len(D2) < 9 Then
      MCC1 = MCC(D1, D2)
      Else
     Dim x, Y ';定义分段长度
    x = Len(D1): Y = Len(D2)
   
 Dim JW, jcc, jss, jcs

   Dim a() As String, b() As String
   
   ReDim a(1 To x)
   ReDim b(1 To Y)
   For I = 1 To x
   a(I) = Mid(D1, I, 1)
   Next
   For J = 1 To Y
   b(J) = Mid(D2, J, 1)
   Next
   jcc = Val(a(1) & a(2)) \ Val(b(1) & b(2))
   
      
         
   jss = MbC(Trim(jcc), D2)
    For i1 = 1 To Y
     jws = jws & a(i1)
       Next
      
       Do While MBJC(Trim(jws), Trim(jss)) = -1
       jcc = jcc - 1
       jss = MbC(Trim(jcc), D2)
       Loop
   JW = MPC(Trim(jws), Trim(jss))
   
     z = x - Y
   
     Dim c() As String
     ReDim c(1 To z)
     For s = 1 To z
      If MBJC(JW & a(s + Y), D2) = -1 Then
        c(s) = "0"
        Else
      jwc = Val(Left(JW & a(s + Y), 3)) \ Val(Left(D2, 2))
       If Len(jwc) > 1 Then
       c(s) = "9"
        Else
         c(s) = jwc
          End If
      
      Do While MBJC(JW & a(s + Y), MbC(Val(c(s)), D2)) = -1
     c(s) = Right(10000 + Val(c(s) - 1), 1)
      Loop
      End If
   
      JW = MPC(JW & a(s + Y), MbC(Val(c(s)), D2))
      
     jcc = jcc & c(s)
     Next s
     If JW = 0 Then
     MCC1 = jcc
     Else
     MCC1 = jcc & "/" & JW
     End If
   
   For I = 1 To Len(MCC1)
     If Not Mid(MCC1, I, 1) = "0" Then
         Exit For
     End If
 Next
 strtmp = Mid(MCC1, I)
   If Len(strtmp) = 0 Then
   MCC1 = "0"
   Else
 MCC1 = strtmp
 End If
   
   
   
     End If
   
   
   
   
   
   
   End If
 End If
 End If
 End Function

比较大小的程序:(注意:除法会调用此程序的,否则除法就无法运行了)

Public Function MBJC(D1 As String, D2 As String) As String ';bijiao
 If Len(D1) <= 10 And Len(D2) <= 10 Then
 If Val(D1) > Val(D2) Then
 MBJC = 1
 Else
 If Val(D1) = Val(D2) Then
 MBJC = 0
 Else
 MBJC = -1
 End If
 End If
 Else

 If Len(D1) > Len(D2) Then
 MBJC = 1
 Else
 If Len(D1) < Len(D2) Then
 MBJC = -1
 Else
 If Len(D1) = Len(D2) Then
 Dim x, Y
 x = Len(D1) \ 4: Y = Len(D2) \ 4
 Dim a() As String, b() As String
 ReDim a(4 To 4 * x + 4)
 ReDim b(4 To 4 * Y + 4)
 If Val(Left(D1, Len(D1) - 4 * x)) > Val(Left(D2, Len(D2) - 4 * Y)) Then
   MBJC = 1
   Else
   If Val(Left(D1, Len(D1) - 4 * x)) < Val(Left(D2, Len(D2) - 4 * Y)) Then
   MBJC = -1
   Else
   For I = 4 To 4 * x Step 4
   a(I) = Mid(D1, Len(D1) - I + 1, 4)
   b(I) = Mid(D2, Len(D2) - I + 1, 4)
   Next
   J = 4 * x
   Do While a(J) = b(J) And J >= 8
   
   J = J - 4
      Loop
      
      
    If Val(a(J)) - Val(b(J)) > 0 Then
    MBJC = 1
    Else
    If Val(a(J)) - Val(b(J)) < 0 Then
    MBJC = -1
    Else
    MBJC = 0
    End If
   
   End If
   
   
   
 End If
 End If
 End If
 End If
 End If
 End If
 End Function
#55
ysr28572021-03-17 20:22
回复 14楼 ysr2857
修改了一下14#楼的程序,这回可能对了,哈哈哈!
实际值:12.9+10.9i, 2+7i, 3.1-1.1i, 7, 3.1+1.1i, 2-7i, 12.9-10.9i, 21
输入:80607000,程序结果:12.9497474683058+10.9497474683058i  1.99999999999999+7i  3.05025253169417+-1.05025253169417i  
7+0i  3.05025253169417+1.05025253169415i  2.00000000000001+-7i  12.9497474683058+-10.9497474683058i  21+0i  

代码如下:
Private Sub Command1_Click()
Dim xr() As Double, a As String
a = Trim(Text1)
ReDim xr(0 To Len(a) - 1)
For i1 = 0 To Len(a) - 1
xr(i1) = Mid(a, i1 + 1, 1)
  Next
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
Dim xi()
n = Len(a) '求数组大小,其值必须是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)

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)
  Print l
  r = 0
Do
  p = r
  Do
   q = p + le1
   
   tr = xr(q) * wr - xi(q) * wi
   ti = xr(q) * wi + xi(q) * wr
   
   xr(q) = xr(p) - tr
   xi(q) = xi(p) - ti
   xr(p) = xr(p) + tr
   xi(p) = xi(p) + ti
   Print p, q
   
   Print xr(p), xr(q)
   
   
   p = p + le
Loop Until p > n - 2


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 '仅输出模
   Text2 = xr(i) & "+" & xi(i) & "i" & "  " & Text2
   Next

End Sub

Private Sub Command2_Click()
Text1 = ""
Text2 = ""
End Sub
#56
ysr28572021-03-17 20:59
修改了一下程序,这回可能对了,哈哈哈!
程序结果:678*432=292896.  123*123=015129.
代码如下:(太激动了,明天再说!)

Private Sub Command1_Click()
 Dim xr() As Double, a As String
 a = Trim(Text1)
 b = Trim(Text3)
 sb1 = Len(a) + Len(b)
 sb2 = Log(sb1) / Log(2)
 If InStr(sb2, ".") = 0 Then
 sb2 = sb2
 Else
 sb2 = Int(sb2) + 1
 End If
 sb = 2 ^ sb2
 Print sb
 If Len(a) = Len(b) And 2 ^ (Int(Log(Len(a)) / Log(2))) = Len(a) Then
  a = String(Val(sb) - Len(a), "0") & a
 b = String(Val(sb) - Len(b), "0") & b
 a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
 Else

 a = String(Val(sb) - Len(a), "0") & a
 b = String(Val(sb) - Len(b), "0") & b
 a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
 End If
 ReDim xr(0 To Len(a) - 1): ReDim yr(0 To Len(b) - 1): ReDim zr(0 To Len(b) - 1)
 For i1 = 0 To Len(a) - 1
 xr(i1) = Mid(a, i1 + 1, 1)
 yr(i1) = Mid(b, i1 + 1, 1)

   Next
 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 xi(): Dim yi(): Dim zi()
 n = Len(a) '求数组大小,其值必须是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
   
    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)
    If InStr(zr(i), ".") = 0 Then
    zr(i) = zr(i)
    Else
    a1 = Left(zr(i), InStr(zr(i), ".") - 1)
    b1 = Mid(zr(i), InStr(zr(i), "."), 3)
    zr(i) = a1 & b1
    End If

    s = s & "/" & zr(i)
    s1 = s1 & "/" & zi(i)
    Next
   s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)))
   s3 = nifft(Trim(s), Trim(s1))
    Text2 = s2
 End Sub

 Private Sub Command2_Click()
 Text1 = ""
 Text2 = ""
 Text3 = ""
 Form1.Cls
 End Sub

 Private Function nifft(sa As String, sb As String) As String
 Dim l As Long, le As Long, le1 As Long, j 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 xi(): Dim yi(): Dim zi()
 Dim xr(), yr(), zr()
 s2 = Split(sa, "/")
 s3 = Split(sb, "/")
    j = UBound(s2)
    n = j
   For k = 1 To j
       n1 = n1 + 1
        ReDim Preserve xr(0 To n1 - 1)
        ReDim Preserve yr(0 To n1 - 1)
       xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
     Next
   

 ReDim zr(0 To j - 1)

 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 = -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
   
    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) - yi(i)) / n
    If InStr(zr(i), ".") = 0 Then
    zr(i) = zr(i)
    Else
    a1 = Left(zr(i), InStr(zr(i), ".") - 1)
    b1 = Mid(zr(i), InStr(zr(i), "."), 3)
    zr(i) = a1 & b1
    End If
   
    s1 = Int(Val(zr(i) + 0.5))
    s = "/" & s1 & s
    zr(i) = s1
    Next
    For i1 = 1 To Val(j / 2 - 1)
    zr(j / 2 + i1) = 0
    Next
   
   
   
    For i1 = 0 To n - 1
    s5 = "/" & Int(zr(i1)) & s5
    If i1 = 0 Then
    s6 = Int(zr(i1)) \ 10
    s8 = Int(zr(i1)) Mod 10
    ElseIf Val(zr(i1)) > 0 Then
    s7 = Int(zr(i1)) + Val(s6)
    s10 = Val(s7) Mod 10
    s11 = s10 & s11
    s6 = Val(s7) \ 10
    Else
    s6 = s6
    End If
   
    Next
    s9 = s6 & s11 & s8
   
 nifft = s9

 End Function

 Private Function dxcx0(sa As String, sb As String) As String

 Dim x_() As Double, a As String
  a = Trim(sa)
  ReDim x_(1 To sb)
  For i1 = 1 To sb
  x_(i1) = Mid(a, sb - i1 + 1, 1)
    Next
  Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
  s = s & x_(j + 1)
  Next
  dxcx0 = x_(1) & x_(1 + sb / 2) & s
  

 End Function

 Private Function dxcx1(sa As String) As String

 Dim x_() As Double, a As String
  a = Trim(sa)
   

 s2 = Split(sa, "/")
 s3 = Split(sb, "/")
    j = UBound(s2)
    sb = j
   
     ReDim x_(1 To sb)
   For k = 1 To j
       n1 = n1 + 1
        ReDim Preserve x_(1 To n1)
      
       x_(n1) = s2(n1)
     Next
  Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
  '位序倒置
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
  s = s & "/" & x_(j + 1)
  Next
  dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
  
  End Function

#57
ysr28572021-03-17 22:41
改进了一下,这回可能是正确了,删掉了最高位的非零数字,代码如下:

Private Sub Command1_Click()
Dim xr() As Double, a As String
a = Trim(Text1)
b = Trim(Text3)
sb1 = Len(a) + Len(b)
sb2 = Log(sb1) / Log(2)
If InStr(sb2, ".") = 0 Then
sb2 = sb2
Else
sb2 = Int(sb2) + 1
End If
sb = 2 ^ sb2
Print sb
If Len(a) = Len(b) And 2 ^ (Int(Log(Len(a)) / Log(2))) = Len(a) Then
  a = String(Val(sb) - Len(a), "0") & a
b = String(Val(sb) - Len(b), "0") & b
a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
Else

a = String(Val(sb) - Len(a), "0") & a
b = String(Val(sb) - Len(b), "0") & b
a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
End If
ReDim xr(0 To Len(a) - 1): ReDim yr(0 To Len(b) - 1): ReDim zr(0 To Len(b) - 1)
For i1 = 0 To Len(a) - 1
xr(i1) = Mid(a, i1 + 1, 1)
yr(i1) = Mid(b, i1 + 1, 1)

   Next
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 xi(): Dim yi(): Dim zi()
n = Len(a) '求数组大小,其值必须是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
   
    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)
    If InStr(zr(i), ".") = 0 Then
    zr(i) = zr(i)
    Else
    a1 = Left(zr(i), InStr(zr(i), ".") - 1)
    b1 = Mid(zr(i), InStr(zr(i), "."), 3)
    zr(i) = a1 & b1
    End If

    s = s & "/" & zr(i)
    s1 = s1 & "/" & zi(i)
    Next
   s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
   s3 = nifft(Trim(s), Trim(s1), Trim(sb1))
    Text2 = s2
End Sub

Private Sub Command2_Click()
Text1 = ""
Text2 = ""
Text3 = ""
Form1.Cls
End Sub

Private Function nifft(sa As String, sb As String, sb1 As String) As String
Dim l As Long, le As Long, le1 As Long, j 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 xi(): Dim yi(): Dim zi()
Dim xr(), yr(), zr()
s2 = Split(sa, "/")
s3 = Split(sb, "/")
    j = UBound(s2)
    n = j
   For k = 1 To j
       n1 = n1 + 1
        ReDim Preserve xr(0 To n1 - 1)
        ReDim Preserve yr(0 To n1 - 1)
       xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
     Next
   

ReDim zr(0 To j - 1)

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 = -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
   
    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) - yi(i)) / n
    If InStr(zr(i), ".") = 0 Then
    zr(i) = zr(i)
    Else
    a1 = Left(zr(i), InStr(zr(i), ".") - 1)
    b1 = Mid(zr(i), InStr(zr(i), "."), 3)
    zr(i) = a1 & b1
    End If
   
    s1 = Int(Val(zr(i) + 0.5))
    s = "/" & s1 & s
    zr(i) = s1
    Next
    For i1 = 1 To Val(j - sb1 + 1)
    zr(sb1 + i1 - 2) = 0
    Next
   
   
   
    For i1 = 0 To n - 1
    s5 = "/" & Int(zr(i1)) & s5
    If i1 = 0 Then
    s6 = Int(zr(i1)) \ 10
    s8 = Int(zr(i1)) Mod 10
    ElseIf Val(zr(i1)) > 0 Then
    s7 = Int(zr(i1)) + Val(s6)
    s10 = Val(s7) Mod 10
    s11 = s10 & s11
    s6 = Val(s7) \ 10
    Else
    s6 = s6
    End If
   
    Next
    s9 = s6 & s11 & s8
   
nifft = s9

End Function

Private Function dxcx0(sa As String, sb As String) As String

Dim x_() As Double, a As String
  a = Trim(sa)
  ReDim x_(1 To sb)
  For i1 = 1 To sb
  x_(i1) = Mid(a, sb - i1 + 1, 1)
    Next
  Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
  s = s & x_(j + 1)
  Next
  dxcx0 = x_(1) & x_(1 + sb / 2) & s
  

End Function

Private Function dxcx1(sa As String) As String

Dim x_() As Double, a As String
  a = Trim(sa)
   

s2 = Split(sa, "/")
s3 = Split(sb, "/")
    j = UBound(s2)
    sb = j
   
     ReDim x_(1 To sb)
   For k = 1 To j
       n1 = n1 + 1
        ReDim Preserve x_(1 To n1)
      
       x_(n1) = s2(n1)
     Next
  Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
  '位序倒置
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
  s = s & "/" & x_(j + 1)
  Next
  dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
  
  End Function

#58
ysr28572021-03-17 23:03
还是有问题,末尾和中间有0的时候就不对了,咋回事呢?再说吧!各位老师晚安!
11111*202=02244422(这个倒是对的),1111111111*101=022321321310(这个不对了),应该是:
1111111111*101=112,222,222,211.

1111111111*202=0224444444422(这个倒是对的),咋回事呢?

再说吧,晚安!!

[此贴子已经被作者于2021-3-17 23:18编辑过]

#59
ysr28572021-03-18 10:28
末尾有0的好处理,中间有0的好像只有101这一个数不对,其他都对?
1111111111*10001=011112222221111(这个是对的),1111111111*1001=1,112,222,222,111(这个也是对的).
哈哈哈!加个前置程序调用这个程序就可以了,前置程序可以处理末尾为0和乘数为101或两个乘数都是101的情况。当然两个都是101的不必处理,只要用普通的计算就可以,不必用大数计算程序。
#60
ysr28572021-03-18 10:45
其中一个是101,只要另一个的位数不超过9位,还是对的:
111111111*101=011222222211,123456789*101=012469135689.

哈哈!就是说这个还是可以用的!
#61
ysr28572021-03-18 13:28
还有其中一个因数为1,11或111的情况,有时候也有不对的,再验证一下,看看还有没有其他情况。
解决办法就是,弄个前置程序调用该程序,并处理各种特殊情况。
#62
ysr28572021-03-18 14:20
还有一种情况有时候不准呢,咋回事,咋就弄准了?
111111111111111111111111*111111=01234566666666666666666666666666666666665754330(不对了),应该是:01234566666666666666666666666666666666666664321.
11111111111111111111111111111*111111=012335666656666666666666666666666666666666666666666666666666666654311(不对了),应该是:012345666666666666666666666666666666666666666666666666666666666654321.

咋回事呢,咋总是有一些算不准呢?

[此贴子已经被作者于2021-3-18 14:21编辑过]

#63
ysr28572021-03-18 19:17
改了一下,还是有不对的,代码如下:

Private Sub Command1_Click()
Dim xr() As Double, a As String
a = Trim(Text1)
b = Trim(Text3)
sb1 = Len(a) + Len(b)
sb2 = Log(sb1) / Log(2)
If InStr(sb2, ".") = 0 Then
sb2 = sb2
Else
sb2 = Int(sb2) + 1
End If
sb = 2 ^ sb2
Print sb
If Len(a) = Len(b) And 2 ^ (Int(Log(Len(a)) / Log(2))) = Len(a) Then
  a = String(Val(sb) - Len(a), "0") & a
b = String(Val(sb) - Len(b), "0") & b
a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
Else

a = String(Val(sb) - Len(a), "0") & a
b = String(Val(sb) - Len(b), "0") & b
a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
End If
ReDim xr(0 To Len(a) - 1): ReDim yr(0 To Len(b) - 1): ReDim zr(0 To Len(b) - 1)
For i1 = 0 To Len(a) - 1
xr(i1) = Mid(a, i1 + 1, 1)
yr(i1) = Mid(b, i1 + 1, 1)

   Next
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 xi(): Dim yi(): Dim zi()
n = Len(a) '求数组大小,其值必须是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
   
    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)
    If InStr(zr(i), ".") = 0 Then
    zr(i) = zr(i)
    Else
    a1 = Left(zr(i), InStr(zr(i), ".") - 1)
    b1 = Mid(zr(i), InStr(zr(i), "."), 5)
    zr(i) = a1 & b1
    End If

    s = s & "/" & zr(i)
    s1 = s1 & "/" & zi(i)
    Next
   s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
   s3 = nifft(Trim(s), Trim(s1), Trim(sb1))
    Text2 = s2
End Sub

Private Sub Command2_Click()
Text1 = ""
Text2 = ""
Text3 = ""
Form1.Cls
End Sub

Private Function nifft(sa As String, sb As String, sb1 As String) As String
Dim l As Long, le As Long, le1 As Long, j 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 xi(): Dim yi(): Dim zi()
Dim xr(), yr(), zr()
s2 = Split(sa, "/")
s3 = Split(sb, "/")
    j = UBound(s2)
    n = j
   For k = 1 To j
       n1 = n1 + 1
        ReDim Preserve xr(0 To n1 - 1)
        ReDim Preserve yr(0 To n1 - 1)
       xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
     Next
   

ReDim zr(0 To j - 1)

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 = -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
   
    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) - yi(i)) / n
    If InStr(zr(i), ".") = 0 Then
    zr(i) = zr(i)
    Else
    a1 = Left(zr(i), InStr(zr(i), ".") - 1)
    b1 = Mid(zr(i), InStr(zr(i), "."), 3)
    zr(i) = a1 & b1
    End If
   
    s1 = Int(Val(zr(i) + 0.5))
    s = "/" & s1 & s
    zr(i) = s1
    Next
    For i1 = 1 To Val(j - sb1 + 1)
    zr(sb1 + i1 - 2) = 0
    Next
   
   
   
    For i1 = 0 To n - 1
    If zr(i1) < 0 Then
    zr(i1) = 0
    Else
    zr(i1) = zr(i1)
    End If
   
    s5 = "/" & Int(zr(i1)) & s5
    If i1 = 0 Then
    s6 = Int(zr(i1)) \ 10
    s8 = Int(zr(i1)) Mod 10
    ElseIf Val(zr(i1)) >= 0 Then
    s7 = Int(zr(i1)) + Val(s6)
    s10 = Val(s7) Mod 10
    s11 = s10 & s11
    s6 = Val(s7) \ 10
    Else
    s6 = Val(s6)
    End If
   
    Next
    s9 = s6 & s11 & s8
   
nifft = s9

End Function

Private Function dxcx0(sa As String, sb As String) As String

Dim x_() As Double, a As String
  a = Trim(sa)
  ReDim x_(1 To sb)
  For i1 = 1 To sb
  x_(i1) = Mid(a, sb - i1 + 1, 1)
    Next
  Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
  s = s & x_(j + 1)
  Next
  dxcx0 = x_(1) & x_(1 + sb / 2) & s
  

End Function

Private Function dxcx1(sa As String) As String

Dim x_() As Double, a As String
  a = Trim(sa)
   

s2 = Split(sa, "/")
s3 = Split(sb, "/")
    j = UBound(s2)
    sb = j
   
     ReDim x_(1 To sb)
   For k = 1 To j
       n1 = n1 + 1
        ReDim Preserve x_(1 To n1)
      
       x_(n1) = s2(n1)
     Next
  Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
  '位序倒置
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
  s = s & "/" & x_(j + 1)
  Next
  dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
  
  End Function

#64
ysr28572021-03-19 11:02
又改进了一下,小数点后面的有效数字全保留,这样居然都对了,就是这样太占空间,再改一下吧,代码如下:

Private Sub Command1_Click()
 Dim xr() As Double, a As String
 a = Trim(Text1)
 b = Trim(Text3)
 sb1 = Len(a) + Len(b)
 sb2 = Log(sb1) / Log(2)
 If InStr(sb2, ".") = 0 Then
 sb2 = sb2
 Else
 sb2 = Int(sb2) + 1
 End If
 sb = 2 ^ sb2
 Print sb
 If Len(a) = Len(b) And 2 ^ (Int(Log(Len(a)) / Log(2))) = Len(a) Then
   a = String(Val(sb) - Len(a), "0") & a
 b = String(Val(sb) - Len(b), "0") & b
 a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
 Else

 a = String(Val(sb) - Len(a), "0") & a
 b = String(Val(sb) - Len(b), "0") & b
 a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
 End If
 ReDim xr(0 To Len(a) - 1): ReDim yr(0 To Len(b) - 1): ReDim zr(0 To Len(b) - 1)
 For i1 = 0 To Len(a) - 1
 xr(i1) = Mid(a, i1 + 1, 1)
 yr(i1) = Mid(b, i1 + 1, 1)

    Next
 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 xi(): Dim yi(): Dim zi()
 n = Len(a) '求数组大小,其值必须是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
   
     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)
     

     s = s & "/" & zr(i)
     s1 = s1 & "/" & zi(i)
     Next
    s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
    s3 = nifft(Trim(s), Trim(s1), Trim(sb1))
     Text2 = s2
 End Sub

 Private Sub Command2_Click()
 Text1 = ""
 Text2 = ""
 Text3 = ""
 Form1.Cls
 End Sub

 Private Function nifft(sa As String, sb As String, sb1 As String) As String
 Dim l As Long, le As Long, le1 As Long, j 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 xi(): Dim yi(): Dim zi()
 Dim xr(), yr(), zr()
 s2 = Split(sa, "/")
 s3 = Split(sb, "/")
     j = UBound(s2)
     n = j
    For k = 1 To j
        n1 = n1 + 1
         ReDim Preserve xr(0 To n1 - 1)
         ReDim Preserve yr(0 To n1 - 1)
        xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
      Next
   

 ReDim zr(0 To j - 1)

 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 = -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
   
     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) - yi(i)) / n
     
   
     s1 = Int(Val(zr(i) + 0.5))
     s = "/" & s1 & s
     zr(i) = s1
     Next
     For i1 = 1 To Val(j - sb1 + 1)
     zr(sb1 + i1 - 2) = 0
     Next
     
   
   
     For i1 = 0 To n - 1
     If zr(i1) < 0 Then
     zr(i1) = 0
     Else
     zr(i1) = zr(i1)
     End If
     
     s5 = "/" & Int(zr(i1)) & s5
     If i1 = 0 Then
     s6 = Int(zr(i1)) \ 10
     s8 = Int(zr(i1)) Mod 10
     ElseIf Val(zr(i1)) >= 0 Then
     s7 = Int(zr(i1)) + Val(s6)
     s10 = Val(s7) Mod 10
     s11 = s10 & s11
     s6 = Val(s7) \ 10
     Else
     s6 = Val(s6)
     End If
   
     Next
     s9 = s6 & s11 & s8
   
 nifft = s9

 End Function

 Private Function dxcx0(sa As String, sb As String) As String

 Dim x_() As Double, a As String
   a = Trim(sa)
   ReDim x_(1 To sb)
   For i1 = 1 To sb
   x_(i1) = Mid(a, sb - i1 + 1, 1)
     Next
   Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
   s = s & x_(j + 1)
   Next
   dxcx0 = x_(1) & x_(1 + sb / 2) & s
   

 End Function

 Private Function dxcx1(sa As String) As String

 Dim x_() As Double, a As String
   a = Trim(sa)
   

 s2 = Split(sa, "/")
 s3 = Split(sb, "/")
     j = UBound(s2)
     sb = j
   
      ReDim x_(1 To sb)
    For k = 1 To j
        n1 = n1 + 1
         ReDim Preserve x_(1 To n1)
      
        x_(n1) = s2(n1)
      Next
   Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
   '位序倒置
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
   s = s & "/" & x_(j + 1)
   Next
   dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
   
   End Function
#65
ysr28572021-03-19 17:20
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*111111111=12345678999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999987654321有116位(这个是对的),有时候中间会出现两个错误数字,咋回事呢?不可靠了?需要再做研究调整!
#66
ysr28572021-03-19 18:55
额,我用差程序了,用的是没有调整好的程序,改回来后结果全是对的,就是速度慢了!!需要研究优化:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有331位,用时2.648438秒.

不知道如何优化,希望老师指点!
#67
ysr28572021-03-19 19:23
优化一下,可以提高速度的,好像是有提升空间:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有331位,用时1.554688秒.
#68
ysr28572021-03-19 20:41
速度基本无法再提高了,改一下算法,改为8位一组试试,如何呢?如下是优化后的代码(还没有改成8位一组的):
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

Private Sub Command1_Click()
  Dim xr() As Double, a As String
  a = Trim(Text1)
  b = Trim(Text3)
  ts = Timer
  sb1 = Len(a) + Len(b)
  sb2 = Log(sb1) / Log(2)
  If InStr(sb2, ".") = 0 Then
  sb2 = sb2
  Else
  sb2 = Int(sb2) + 1
  End If
  sb = 2 ^ sb2
  Print sb
  If Len(a) = Len(b) And 2 ^ (Int(Log(Len(a)) / Log(2))) = Len(a) Then
    a = String(Val(sb) - Len(a), "0") & a
  b = String(Val(sb) - Len(b), "0") & b
  a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
  Else

  a = String(Val(sb) - Len(a), "0") & a
  b = String(Val(sb) - Len(b), "0") & b
  a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
  End If
  ReDim xr(0 To Len(a) - 1): ReDim yr(0 To Len(b) - 1): ReDim zr(0 To Len(b) - 1)
  For i1 = 0 To Len(a) - 1
  xr(i1) = Mid(a, i1 + 1, 1)
  yr(i1) = Mid(b, i1 + 1, 1)

     Next
  
  Dim xi(): Dim yi(): Dim zi()
  n = Len(a) '求数组大小,其值必须是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
     
      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)
      

      s = s & "/" & zr(i)
      s1 = s1 & "/" & zi(i)
      Next
     s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
     
      Text2 = s2 & "有" & Len(s2) & "位,用时" & Timer - ts & "秒"
  End Sub

  Private Sub Command2_Click()
  Text1 = ""
  Text2 = ""
  Text3 = ""
  Form1.Cls
  End Sub

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


  Private Function nifft(sa As String, sb As String, sb1 As String) As String
  
  Dim xi(): Dim yi(): Dim zi()
  Dim xr(), yr(), zr()
  s2 = Split(sa, "/")
  s3 = Split(sb, "/")
      j = UBound(s2)
      n = j
     For k = 1 To j
         n1 = n1 + 1
          ReDim Preserve xr(0 To n1 - 1)
          ReDim Preserve yr(0 To n1 - 1)
         xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
       Next
     

  ReDim zr(0 To j - 1)

  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 = -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
     
      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) - yi(i)) / n
      
     
      s1 = Int(Val(zr(i) + 0.5))
      s = "/" & s1 & s
      zr(i) = s1
      Next
      For i1 = 1 To Val(j - sb1 + 1)
      zr(sb1 + i1 - 2) = 0
      Next
      
     
     
      For i1 = 0 To n - 1
      If zr(i1) < 0 Then
      zr(i1) = 0
      Else
      zr(i1) = zr(i1)
      End If
      
      
      If i1 = 0 Then
      s6 = Int(zr(i1)) \ 10
      s8 = Int(zr(i1)) Mod 10
      ElseIf Val(zr(i1)) >= 0 Then
      s7 = Int(zr(i1)) + Val(s6)
      s10 = Val(s7) Mod 10
      s11 = s10 & s11
      s6 = Val(s7) \ 10
      Else
      s6 = Val(s6)
      End If
     
      Next
      s9 = s6 & s11 & s8
     
  nifft = qdqd0(Trim(s9))

  End Function

  Private Function dxcx0(sa As String, sb As String) As String

  Dim x_() As Double, a As String
    a = Trim(sa)
    ReDim x_(1 To sb)
    For i1 = 1 To sb
    x_(i1) = Mid(a, sb - i1 + 1, 1)
      Next
    Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
    s = s & x_(j + 1)
    Next
    dxcx0 = x_(1) & x_(1 + sb / 2) & s
   

  End Function

  Private Function dxcx1(sa As String) As String

  Dim x_() As Double, a As String
    a = Trim(sa)
     

  s2 = Split(sa, "/")
  s3 = Split(sb, "/")
      j = UBound(s2)
      sb = j
     
       ReDim x_(1 To sb)
     For k = 1 To j
         n1 = n1 + 1
          ReDim Preserve x_(1 To n1)
        
         x_(n1) = s2(n1)
       Next
    Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
    '位序倒置
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
    s = s & "/" & x_(j + 1)
    Next
    dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
   
    End Function

[此贴子已经被作者于2021-3-19 20:42编辑过]

#69
ysr28572021-03-19 23:20
好像能运行了,计算小的数值末尾多了1,程序结果:12345678*23456789=289589963907943有15位,用时0秒,实际为:289589963907942.
咋回事呢?速度快了反而不可靠了?代码如下:(改天再研究吧)

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

Private Sub Command1_Click()
  Dim xr() As String, a As String
  a = Trim(Text1)
  b = Trim(Text3)
  ts = Timer
  x = Len(a) \ 8: Y = Len(b) \ 8
  If Val(8 * x) = Len(a) Then
  a = a
  ElseIf Val(8 * Y) = Len(b) Then
  b = b
  Else
  a = InStr(Val(x * 8 + 8 - Len(a)), "0") & a
  b = InStr(Val(Y * 8 + 8 - Len(b)), "0") & b
  x = x + 1: Y = Y + 1
  End If
  
  
  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
  Print sb
  

  a = String(Val(sb) * 8 - Len(a), "0") & a
  b = String(Val(sb) * 8 - Len(b), "0") & b
  a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
  Print a
  ReDim xr(0 To (Len(a) - 8) \ 8): ReDim yr(0 To (Len(b) - 8) \ 8): ReDim zr(0 To (Len(b) - 8) \ 8)
  If Len(a) = 8 Then
  xr(0) = a: yr(0) = b
  Else
  For i1 = 0 To (Len(a) - 8) \ 8
  xr(i1) = Mid(a, (i1 + 1) * 8 - 7, 8)
  yr(i1) = Mid(b, (i1 + 1) * 8 - 7, 8)

     Next
     End If
  
  Dim xi(): Dim yi(): Dim zi()
  n = Len(a) \ 8 '求数组大小,其值必须是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
     
      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)
      

      s = s & "/" & zr(i)
      s1 = s1 & "/" & zi(i)
      Next
     s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
     
      Text2 = s2 & "有" & Len(s2) & "位,用时" & Timer - ts & "秒"
  End Sub

  Private Sub Command2_Click()
  Text1 = ""
  Text2 = ""
  Text3 = ""
  Form1.Cls
  End Sub

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


  Private Function nifft(sa As String, sb As String, sb1 As String) As String
  
  Dim xi(): Dim yi(): Dim zi()
  Dim xr(), yr()
  Dim zr() As String
  
  s2 = Split(sa, "/")
  s3 = Split(sb, "/")
      j = UBound(s2)
      n = j
     For k = 1 To j
         n1 = n1 + 1
          ReDim Preserve xr(0 To n1 - 1)
          ReDim Preserve yr(0 To n1 - 1)
         xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
       Next
     

  ReDim zr(0 To j - 1)

  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 = -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
     
      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) - yi(i)) / n
      
     
      s1 = Int(Val(zr(i) + 0.5))
      s = "/" & s1 & s
      zr(i) = s1
      Next
      For i1 = 1 To Val(j - sb1 + 1)
      zr(sb1 + i1 - 2) = 0
      Next
      
     
     
      For i1 = 0 To n - 1
      If zr(i1) < 0 Then
      zr(i1) = 0
      Else
      zr(i1) = Format(zr(i1), "#")
      End If
      
      
      If i1 = 0 Then
      If Len(zr(i1)) < 8 Then
      zr(i1) = InStr(8 - Len(zr(i1)), "0") & zr(i1)
      Else
      zr(i1) = zr(i1)
      End If
      s6 = Val(Left(zr(i1), Len(zr(i1)) - 8))
      If Len(s6) < 8 Then
      s6 = InStr(8 - Len(s6), "0") & s6
      Else
      s6 = s6
      End If
      s8 = Right(zr(i1), 8)
      ElseIf Val(zr(i1)) >= 0 Then
      s7 = Val(zr(i1)) + Val(s6)
      s10 = Right(s7, 8)
      s11 = s10 & s11
      If Len(s7) < 8 Then
      s7 = InStr(8 - Len(s7), "0") & s7
      ElseIf Len(s7) = 8 Then
      s6 = "00000000"
      Else
      s7 = s7
      s6 = Val(Left(s7, Len(s7) - 8))
      End If
      Else
      s6 = s6
      End If
     
      Next
      s9 = s6 & s11 & s8
     
  nifft = qdqd0(Trim(s9))

  End Function

  Private Function dxcx0(sa As String, sb As String) As String

  Dim x_() As String, a As String
    a = Trim(sa)
    ReDim x_(1 To sb)
    For i1 = 1 To sb
    x_(i1) = Mid(a, (sb - i1 + 1) * 8 - 7, 8)
    If Len(x_(i1)) < 8 Then
    x_(i1) = InStr(8 - Len(x_(i1)), "0") & x_(i1)
    Else
    x_(i1) = x_(i1)
    End If
   
      Next
    Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
    s = s & x_(j + 1)
    Next
    dxcx0 = x_(1) & x_(1 + sb / 2) & s
   
   

  End Function

  Private Function dxcx1(sa As String) As String

  Dim x_() As Double, a As String
    a = Trim(sa)
     

  s2 = Split(sa, "/")
  s3 = Split(sb, "/")
      j = UBound(s2)
      sb = j
     
       ReDim x_(1 To sb)
     For k = 1 To j
         n1 = n1 + 1
          ReDim Preserve x_(1 To n1)
        
         x_(n1) = s2(n1)
       Next
    Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
    '位序倒置
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
    s = s & "/" & x_(j + 1)
    Next
    dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
   
    End Function







[此贴子已经被作者于2021-3-19 23:29编辑过]

#70
ysr28572021-03-19 23:36
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=11111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有377位,用时0.328125秒。

速度够快,末尾好像也对,高位多了那么多0,咋回事?377-331=46,多了46个1?咋回事呢?

[此贴子已经被作者于2021-3-20 08:13编辑过]

#71
ysr28572021-03-20 00:27
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*9=9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999有100位,用时7.092285E-02秒.
晚安吧!还有客人呢?祝愿各位老师做个好梦,您安好!
#72
ysr28572021-03-20 08:46
12345678*23456789=289289589963907942有18位,用时0.015625秒(这个不对,最高位咋多了3位呢? 应该是15位:289589963907942).
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*9=1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*9=999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999有96位,用时0.1230469秒(这个不对,咋又少了4位?应该是100位).
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有423位,用时0.5546875秒(这个不对,应该是331位,咋多了423-331=92位?).
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有324位,用时0.546875秒(哈哈,这个可能是对的)。

这都是修改以后的程序结果,修改为4位一组了。
#73
ysr28572021-03-20 18:22
如下程序是没有优化的,比前面多加了一个去掉前导0的程序,虽然速度慢运行可靠,结果准确,需要优化,重发一下,希望老师帮助优化程序提高速度,谢谢您!

Private Sub Command1_Click()
 Dim xr() As Double, a As String
 a = Trim(Text1)
 b = Trim(Text3)
 ts = Timer
 sb1 = Len(a) + Len(b)
 sb2 = Log(sb1) / Log(2)
 If InStr(sb2, ".") = 0 Then
 sb2 = sb2
 Else
 sb2 = Int(sb2) + 1
 End If
 sb = 2 ^ sb2
 Print sb
 If Len(a) = Len(b) And 2 ^ (Int(Log(Len(a)) / Log(2))) = Len(a) Then
   a = String(Val(sb) - Len(a), "0") & a
 b = String(Val(sb) - Len(b), "0") & b
 a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
 Else

 a = String(Val(sb) - Len(a), "0") & a
 b = String(Val(sb) - Len(b), "0") & b
 a = dxcx0(Trim(a), Val(sb)): b = dxcx0(Trim(b), Val(sb))
 End If
 ReDim xr(0 To Len(a) - 1): ReDim yr(0 To Len(b) - 1): ReDim zr(0 To Len(b) - 1)
 For i1 = 0 To Len(a) - 1
 xr(i1) = Mid(a, i1 + 1, 1)
 yr(i1) = Mid(b, i1 + 1, 1)

    Next
 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 xi(): Dim yi(): Dim zi()
 n = Len(a) '求数组大小,其值必须是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
   
     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)
     

     s = s & "/" & zr(i)
     s1 = s1 & "/" & zi(i)
     Next
    s2 = nifft(dxcx1(Trim(s)), dxcx1(Trim(s1)), Trim(sb1))
     Text2 = s2 & "有" & Len(s2) & "位,用时" & Timer - ts & "秒"
 End Sub

 Private Sub Command2_Click()
 Text1 = ""
 Text2 = ""
 Text3 = ""
 Form1.Cls
 End Sub

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

 Private Function nifft(sa As String, sb As String, sb1 As String) As String
 Dim l As Long, le As Long, le1 As Long, j 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 xi(): Dim yi(): Dim zi()
 Dim xr(), yr(), zr()
 s2 = Split(sa, "/")
 s3 = Split(sb, "/")
     j = UBound(s2)
     n = j
    For k = 1 To j
        n1 = n1 + 1
         ReDim Preserve xr(0 To n1 - 1)
         ReDim Preserve yr(0 To n1 - 1)
        xr(n1 - 1) = s2(n1): yr(n1 - 1) = s3(n1)
      Next
   

 ReDim zr(0 To j - 1)

 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 = -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
   
     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) - yi(i)) / n
     
   
     s1 = Int(Val(zr(i) + 0.5))
     zr(i) = s1
     Next
     For i1 = 1 To Val(j - sb1 + 1)
     zr(sb1 + i1 - 2) = 0
     Next
     
   
   
     For i1 = 0 To n - 1
     If zr(i1) < 0 Then
     zr(i1) = 0
     Else
     zr(i1) = zr(i1)
     End If
     
     If i1 = 0 Then
     s6 = Int(zr(i1)) \ 10
     s8 = Int(zr(i1)) Mod 10
     ElseIf Val(zr(i1)) >= 0 Then
     s7 = Int(zr(i1)) + Val(s6)
     s10 = Val(s7) Mod 10
     s11 = s10 & s11
     s6 = Val(s7) \ 10
     Else
     s6 = Val(s6)
     End If
   
     Next
     s9 = s6 & s11 & s8
   
 nifft = qdqd0(Trim(s9))

 End Function

 Private Function dxcx0(sa As String, sb As String) As String

 Dim x_() As Double, a As String
   a = Trim(sa)
   ReDim x_(1 To sb)
   For i1 = 1 To sb
   x_(i1) = Mid(a, sb - i1 + 1, 1)
     Next
   Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, 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
   s = s & x_(j + 1)
   Next
   dxcx0 = x_(1) & x_(1 + sb / 2) & s
   

 End Function

 Private Function dxcx1(sa As String) As String

 Dim x_() As Double, a As String
   a = Trim(sa)
   

 s2 = Split(sa, "/")
 s3 = Split(sb, "/")
     j = UBound(s2)
     sb = j
   
      ReDim x_(1 To sb)
    For k = 1 To j
        n1 = n1 + 1
         ReDim Preserve x_(1 To n1)
      
        x_(n1) = s2(n1)
      Next
   Dim n As Integer, i As Long, mn As Long, lh As Long, t As Double
   '位序倒置
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
   s = s & "/" & x_(j + 1)
   Next
   dxcx1 = "/" & x_(1) & "/" & x_(1 + sb / 2) & s
   
   End Function
#74
ysr28572021-03-20 18:32
优化没有完成的程序结果,比没有优化的速度提高了一点,略有提高:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有324位,用时0.5078125秒
#75
ysr28572021-03-20 18:47
这个是模仿手工计算的程序结果,在几百位以内还是快的,比傅立叶变换还快?结果如下:
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有324位,用时0秒.

看起来,最快的是数论变换,有必要学习探讨沟通一下,先优化一下这个程序,不行的话继续研究学习数论变换以得到更快的程序。
#76
ysr28572021-03-21 00:08
回复 72楼 ysr2857
1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=112222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有324位,用时0.1849976秒(这是4位一组的程序结果,速度还有提升空间)
#77
ysr28572021-03-21 00:11
回复 67楼 ysr2857
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111*101=1122222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222211有331位,用时0.1830444秒(速度还有提升空间)
#78
ysr28572021-04-18 21:50
55#楼的程序,就是蝶形算法快速变换,重发一下这个程序及计算举例的程序结果:
实际值:12.9+10.9i, 2+7i, 3.1-1.1i, 7, 3.1+1.1i, 2-7i, 12.9-10.9i, 21
输入:80607000,程序结果:12.9497474683058+10.9497474683058i  1.99999999999999+7i  3.05025253169417+-1.05025253169417i  
7+0i  3.05025253169417+1.05025253169415i  2.00000000000001+-7i  12.9497474683058+-10.9497474683058i  21+0i  

代码如下:
Private Sub Command1_Click()
Dim xr() As Double, a As String
a = Trim(Text1)
ReDim xr(0 To Len(a) - 1)
For i1 = 0 To Len(a) - 1
xr(i1) = Mid(a, i1 + 1, 1)
  Next
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
Dim xi()
n = Len(a) '求数组大小,其值必须是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)

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)
  Print l
  r = 0
Do
  p = r
  Do
   q = p + le1
   
   tr = xr(q) * wr - xi(q) * wi
   ti = xr(q) * wi + xi(q) * wr
   
   xr(q) = xr(p) - tr
   xi(q) = xi(p) - ti
   xr(p) = xr(p) + tr
   xi(p) = xi(p) + ti
   Print p, q
   
   Print xr(p), xr(q)
   
   
   p = p + le
Loop Until p > n - 2


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 '仅输出模
   Text2 = xr(i) & "+" & xi(i) & "i" & "  " & Text2
   Next

End Sub

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

其中用到的三角函数公式是两角和的公式,推到证明如下:
程序中的点值的正弦余弦是用如下公式计算的:
cos(θ + δ) = cosθ - [ α cosθ+ βsinθ ]
sin(θ + δ) = sinθ - [ α sinθ- βcosθ ]其中 α, β 是预先计算的系数:α = 2 (sin(δ/2))^2,β = sinδ 。这个公式对吗?下面证明:
因为α = 2 [sin(δ/2)]^2,β = sinδ ,

所以,cosθ - [ α cosθ+ βsinθ ]={1-2 [sin(δ/2)]^2}cosθ-sinδsinθ= cosθcosδ-sinθsinδ=cos(θ + δ).

sinθ - [ α sinθ- βcosθ ]={1-2 [sin(δ/2)]^2}sinθ+sinδ cosθ=cosδsinθ+sinδ cosθ=sin(θ + δ).

当θ=0时公式变为:
cos(θ + δ) = cosθ - [ α cosθ+ βsinθ ]=1-α
sin(θ + δ) = sinθ - [ α sinθ- βcosθ ]=β
α = 2 (sin(δ/2))^2.
这里的快速傅里叶变换中好像就是这么用的,其中的cosδ和sinδ经常乘以1或0,大概就是这样子。
这里δ=π/n,而不再是2π/n,这样得到的三角函数值可能是更精确一些。如果不精确,则对称性不对称了,共轭复数不共轭了,逆变换就会出错,尤其大数据中间即使有一个数字出错,那也是无法修正的,那程序就无法用了。
#79
xulaoban2022-03-27 20:34
你好 这个FFT蝶形运算代码 我在网上也看到了  但是运用在VB中 对数据做FFT获取频率时   现实的频率还是不对  而且基本是五秒显示一次   (需要的是一秒变换一次)  这个代码写好了吗
#80
ysr28572022-03-29 10:32
回复 79楼 xulaoban
您可以试试下面这个:
蝶形运算程序:(自己试编的)
输入:80607000(接倒序程序的输出),输出:21+0i  12.9497474683058+-10.9497474683058i  2.00000000000001+-7i  3.05025253169417+1.05025253169416i  7+0i  3.05025253169417+-1.05025253169417i  1.99999999999999+7i  12.9497474683058+10.9497474683058i。代码如下:
Private Sub Command1_Click() '蝶形运算程序
Dim xr() As Double, a As String
a = Trim(Text1)
ReDim xr(0 To Len(a) - 1)
For i1 = 0 To Len(a) - 1
xr(i1) = Mid(a, i1 + 1, 1)
  Next
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
Dim xi()
n = Len(a) '求数组大小,其值必须是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)

l = 1
Do
  le = 2 ^ l
  le1 = le / 2
  Print l
  r = 0
Do
  p = r
  Do
   q = p + le1
   
   tr = xr(q) * Cos((-2 * pi / 2 ^ l) * r)
   ti = xr(q) * Sin((-2 * pi / 2 ^ l) * r)
   
   xr(q) = xr(p) - tr
   xi(q) = xi(p) - ti
   xr(p) = xr(p) + tr
   xi(p) = xi(p) + ti
   Print p, q
   
   Print xr(p); xi(p); r, xr(q); xi(q); r
   
   
   p = p + le
Loop Until p > n - 2


r = r + 1
Loop Until r > le1 - 1
l = l + 1
Loop Until l > m

For i = 0 To n - 1 '输出点值
Print xr(i), xi(i)
   Text2 = Text2 & "  " & xr(i) & "+" & xi(i) & "i"
   Next

End Sub

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

这个前面还要加上个倒序程序:
倒序程序:
输入:000678,输出:80607000。代码如下:
Private Sub Command1_Click()
 Dim x_() As Double, a As String
 a = Trim(Text1)
 x = Len(a): y = Int(Log(x) / Log(2)): y = y + 1
 x = 2 ^ y
 a = String(x - Len(a), "0") & a
 ReDim x_(1 To Len(a))
 For i1 = 1 To Len(a)
 x_(i1) = Mid(a, Len(a) - i1 + 1, 1)
   Next
 Dim n As Integer, i As Long, j As Long, mn As Long, lh As Long, t As Double, k As Long
 '位序倒置
n = Len(a) '求数组大小,其值必须是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
 Text2 = Text2 & x_(j + 1)
 Next
 Text2 = x_(1) & x_(1 + Len(a) / 2) & Text2
 
 End Sub

 Private Sub Command2_Click()
 Text1 = ""
 Text2 = ""
 End Sub
#81
独木星空2022-03-30 09:24
回复 80楼 ysr2857
有时间多向ysr2857先生学习。
#82
xulaoban2022-03-30 14:56
回复 80楼 ysr2857
好的 谢谢你 我看一下代码试下 麻烦你了  前几天私信你了
#83
xulaoban2022-03-30 15:16
回复 80楼 ysr2857
(这个是我现在用的,我看了基本好像是差不多,有的应该是变量不同,麻烦有空帮忙看下错在哪里了 感激不尽!)

Option Explicit
  
'*模块********************************************************
'FFT0 数组下标以0开始
'AR() 数据实部         AI() 数据虚部
'N 数据点数,为2的整数次幂
'NI 变换方向 1为正变换,-1为反变换
'***************************************************************
Public Jieguo() As Double
      
Const pi = 3.1415926
Public Function FFT0(AR() As Double, AI() As Double, n As Long, ni As Double)
    Dim i As Long, j As Long, k As Long, L As Long, m As Long
    Dim IP As Double, LE As Double
    Dim L1 As Double, N1 As Double, N2 As Double
    Dim SN As Double, TR As Double, TI As Double, WR As Double, WI As Double
    Dim UR As Double, UI As Double, US As Double
    m = NTOM(n)
    N2 = n / 2
    N1 = n - 1
    SN = ni
    j = 1
    For i = 1 To N1
        If i < j Then
            TR = AR(j - 1)
            AR(j - 1) = AR(i - 1)
            AR(i - 1) = TR
            TI = AI(j - 1)
            AI(j - 1) = AI(i - 1)
            AI(i - 1) = TI
        End If
        k = N2
        While (k < j)
            j = j - k
            k = k / 2
        Wend
        j = j + k
    Next i
    For L = 1 To m
        LE = 2 ^ L
        L1 = LE / 2
        UR = 1#
        UI = 0#
        WR = Cos(pi / L1)
        WI = SN * Sin(pi / L1)
        For j = 1 To L1
            For i = j To n Step LE
                IP = i + L1
                TR = AR(IP - 1) * UR - AI(IP - 1) * UI
                TI = AI(IP - 1) * UR + AR(IP - 1) * UI
                AR(IP - 1) = AR(i - 1) - TR
                AI(IP - 1) = AI(i - 1) - TI
                AR(i - 1) = AR(i - 1) + TR
                AI(i - 1) = AI(i - 1) + TI
            Next i
            US = UR
            UR = US * WR - UI * WI
            UI = UI * WR + US * WI
        Next j
    Next L
    If SN <> -1 Then
        For i = 1 To n
            AR(i - 1) = AR(i - 1) / n
            AI(i - 1) = AI(i - 1) / n
        Next i
    End If
End Function
  
Private Function NTOM(n As Long) As Long
    Dim ND As Single
    ND = n
    NTOM = 0
    While (ND > 1)
        ND = ND / 2
        NTOM = NTOM + 1
    Wend
End Function

Public Function GetArrayMax(a() As Double) As Double
    Dim max As Double, min As Double, i As Integer
    max = a(0)
    min = a(0)
    For i = 1 To UBound(a) - 1
        If max < a(i) Then max = a(i)
        If min > a(i) Then min = a(i)
    Next i
    GetArrayMax = max
End Function

Public Function SSSS()
    Dim ii As Integer, nChannel As Integer, Index As Integer
    Dim xr() As Double
    Dim xi() As Double
    Dim TongDaoShu As Integer, EveryTDPoint As Long
    Dim arrmax As Double
    Writelog "进入循环!"
    Do While (bAIRun)
        Do While (bAIRun)
            If WaitForSingleObject(hEventDRAW, 10) = 0 Then
                Exit Do
            End If
        Loop
        
         'Status = WaitForSingleObject(hEventDRAW, INFINITE)
         If bAIRun = False Then
             Exit Function
         End If
        TongDaoShu = AD_Module.Para.nSampChanCount
        EveryTDPoint = AD_Module.Para.nPointsPerChan
        CurrentIndex = AD_Module.CurrentIndex
        Writelog TongDaoShu & " - " & EveryTDPoint & " - " & CurrentIndex
        
        ReDim xr(EveryTDPoint) As Double
        ReDim xi(EveryTDPoint) As Double
        For Index = 0 To EveryTDPoint - 1 Step 1
        DoEvents
            'Writelog Str(nChannel) + " " + Str(Index) + " " + Str(AD_Module.InUserRegion(nChannel + Index, CurrentIndex))
            For nChannel = 0 To TongDaoShu - 1 Step 1
                xr(Index) = AD_Module.InUserRegion(nChannel + Index, CurrentIndex)
                xi(Index) = 0
            Next nChannel
            Call FFT0(xr(), xi(), EveryTDPoint, 1)
         Next Index
         arrmax = GetArrayMax(xr())
         Writelog Str(arrmax)
         AD_Form.TongDaoHz(nChannel - 1).Caption = arrmax
'        For Channel = 0 To TongDaoShu - 1 Step 1
'            Writelog Channel
'            ReDim xr(EveryTDPoint) As Long
'            ReDim xr(EveryTDPoint) As Long
'            DoEvents
'            For Index = 0 To EveryTDPoint * TongDaoShu - 1 Step TongDaoShu
'                DoEvents
'                xr(Index / TongDaoShu) = AD_Module.InUserRegion(Channel + Index, CurrentIndex)
'                xi(Index / TongDaoShu) = 0
'            Next Index
'            Call FFT0(xr(), xi(), EveryTDPoint, 1)
'            AD_Form.TongDaoHz(Channel).Caption = GetArrayMax(xr())
'        Next Channel
        Writelog "完成循环!"
    Loop
End Function

Public Sub Writelog(ByVal message As String)
'Write Error LogFile

'    Dim ifile As Long
'    ifile = FreeFile
'    Open App.Path & "\log\" & Format(Now, "YYYYMMDD") & ".txt" For Append As #ifile
'    Write #ifile, CStr(Now) & "---(): " & message
'    Close #ifile
     
End Sub

#84
ysr28572022-03-31 10:10
回复 83楼 xulaoban
我的代码是针对数字的,就是把数字(多项式表示法)变为点值表示法,至于速度是每秒显示几个点我还不知道如何弄。
您可以试试把位数n提高一下试试,如何?就是处理256位的数字改为处理512位的或者1024位的。
#85
xulaoban2022-04-02 20:56
回复 84楼 ysr2857
我的是处理1024点或者2048点 取极值做FFT得到频率    例如2048为一组  一秒采集一次一组  每一秒都是采集2048个点,这一组里的最高值做FFT 得到频率,然后下一秒又采取2048个点 做FFT 得到一个频率
#86
独木星空2022-04-02 22:00
回复 84楼 ysr2857
对于一个问题的认知程度,往往是在不断的讨论中加深的。祝你们更上一层楼。
#87
ysr28572022-04-03 06:53
回复 83楼 xulaoban
修改如下这段程序试试:
Next i
            US = UR
            UR = US * WR - UI * WI
            UI = UI * WR + US * WI
        Next j

改为:
Next i
            US = UR
            UR2 = US * WR - UI * WI
            UI2 = UI * WR + US * WI
           US=UR2
          UI=UI2
        Next j

个见,仅供参考!
#88
独木星空2022-04-03 07:33
这个版块的排序,或许与vfp的不同,此版块最新回复会顶上来,而vfp版块只能在它的一个周期内待着。
#89
xulaoban2022-04-03 20:45
回复 87楼 ysr2857
好的,谢谢 过两天采集卡回来我试一下 在看卡结果如何 反馈下
#90
独木星空2022-04-04 11:23
回复 84楼 ysr2857
从来没有往哪里想过,可能与自己的能力有关。
12