vba excel 2003中的素数

tin*_*tes 1 excel vba excel-2003 excel-vba

我正在分析网站上的代码,我也在我身边尝试过,但似乎不起作用.你能告诉我为什么吗?非常感谢你的帮助.

谢谢

Private Sub CommandButton1_Click()
    Dim N, D As Single
    Dim tag As String

    N = Cells(2, 2)
    Select Case N
        Case Is < 2
            MsgBox "It is not a prime number"
        Case Is = 2
            MsgBox "It is a prime number"
        Case Is > 2
            D = 2
            Do
                If N / D = Int(N / D) Then
                    MsgBox "It is not a prime number"
                    tag = "Not Prime"
                    Exit Do
                End If
                D = D + 1
            Loop While D <= N - 1
            If tag <> "Not Prime" Then
                MsgBox "It is a prime number"
            End If
    End Select
End Sub
Run Code Online (Sandbox Code Playgroud)

Ben*_*ack 7

我看到的最大问题是使用Single而不是IntegerLong.素数是正整数,在十进制值的背景下没有考虑(据我所知).因此,通过使用单个元素并将它们与分割的整数进行比较,您可以打开令人讨厌的边缘情况路由错误.

该线路If N / D = Int(N / D) Then使用一种不好的方法来查看数字是否为素数.它假设你每次用除数除以一个浮点数(在这种情况下,单)时,如果有小数点余数,那么其余的整数转换将是不相等的.但是,在尝试比较答案时,我遇到了有时使用浮点数的舍入错误,而且一般来说,我已经学会了避免使用浮点到int转换作为比较数字的方法.

以下是您可能会尝试的一些代码.有些事情需要注意:

  • 我已经改变了N和D的类型,因此它们是Longs而不是Singles.这意味着它们不是浮点数并且可能存在舍入误差.
  • 我还明确地将单元格值转换为long.这样您就可以在代码中知道您没有使用浮点类型.
  • 为了比较,我使用了Mod,它返回N除以的余数D.如果余数为0,则返回true,我们知道我们没有素数.(注:其余为通常与使用\,其中仅返回除法运算的结果的整数值. Mod\在整数类型,在这种情况下是非常合适的精确分割常用.
  • 最后,我更改了您的消息框以显示正在比较的实际数字.由于单元格中的数字被转换,如果用户输入浮点值,它们将有助于查看它被转换为什么.

你可能也注意到,该代码运行了很多比你的代码运行得更快,当你到高数量在数亿."

Sub GetPrime()
Dim N As Long
Dim D As Long
Dim tag As String

N = CLng(Cells(2, 2))

Select Case N
    Case Is < 2
        MsgBox N & " is not a prime number"
    Case Is = 2
        MsgBox N & " is a prime number"
    Case Is > 2
        D = 2
        Do
            If N Mod D = 0 Then
                MsgBox N & " is not a prime number"
                tag = "Not Prime"
                Exit Do
            End If
            D = D + 1
        Loop While D <= N - 1
        If tag <> "Not Prime" Then
            MsgBox N & " is a prime number"
        End If
End Select
End Sub
Run Code Online (Sandbox Code Playgroud)

注意:我更改了程序的名称GetPrime.在您的代码中,您有:

Private Sub CommandButton1_Click()
Run Code Online (Sandbox Code Playgroud)

在上面的行中,您正在定义一个过程(也称为方法,有时也称为子过程).这个词Sub表示您在代码中定义了一个不返回值的过程.(有时您可能会看到该单词Function而不是Sub.这意味着该过程返回一个值,例如Private Function ReturnANumber() As Long.)procedure(Sub)是一个在调用时执行的代码体.另外值得注意的是,excel宏作为Sub过程存储在VBA中.

在您的代码行中,CommandButton1_Click()是过程的名称.最有可能的是,这是通过向Excel电子表格添加按钮自动创建的.如果按钮绑定到Excel电子表格,CommandButton1_Click()则每次按下按钮时都会执行.

在您的代码中,Private指示过程的范围. Private通常意味着不能在它所驻留的模块或类之外调用该过程.在我的代码中,我遗漏了,Private因为你可能想GetPrime从不同的代码模块调用.

您在评论中提到您必须将我的程序名称更改GetPrime()CommandButton1_Click().这当然有效.但是,您也可以GetPrime内部 简单地调用CommandButton1_Click(),如下所示:

Private Sub CommandButton1_Click()
    'The following line of code will execute GetPrime()  '
    'Since GetPrime does not have parameters and does not return a value, '
    'all you need to do is put the name of the procedure without the ()   '
    GetPrime
End Sub

'Below is the entire code for the Sub GetPrime()    '
Sub GetPrime()
    'The body of the code goes below: '
    ' ... '

End Sub
Run Code Online (Sandbox Code Playgroud)

希望这有助于解释VBA以进一步理解你的理解!