Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
vba excel 2003中的素数_Excel_Vba_Excel 2003 - Fatal编程技术网

vba excel 2003中的素数

vba excel 2003中的素数,excel,vba,excel-2003,Excel,Vba,Excel 2003,我正在分析网站上的一段代码,我也尝试过,但似乎不起作用。你能告诉我为什么吗?非常感谢你的帮助 谢谢 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

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

谢谢

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
Private子命令按钮1\u单击()
暗N,D为单色
作为字符串的Dim标记
N=单元(2,2)
选择案例N
病例<2例
MsgBox“它不是质数”
情况是=2
MsgBox“它是一个素数”
案例>2
D=2
做
如果N/D=Int(N/D),则
MsgBox“它不是质数”
tag=“非素数”
退出Do
如果结束
D=D+1

循环而D我看到的最大问题是使用
single
而不是
Integer
Long
。素数是正整数,在十进制值的上下文中不被考虑(据我所知)。因此,通过使用单数并将其与整数进行比较,您将面临严重的边缘情况错误

如果N/D=Int(N/D),则
使用了一种糟糕的方法来查看数字是否为素数。假设每次将浮点数(在本例中为单)除以除数时,如果它有十进制余数,则该余数的整数转换将不相等。然而,在比较答案时,我有时会遇到浮点数字的舍入错误,一般来说,我学会了避免使用浮点到整数的转换作为比较数字的方法

这里有一些代码,你可以试试。需要注意的一些事项:

  • 我改变了N和D的类型,使它们是长的而不是单的。这意味着它们不是浮点型,并且可能存在舍入错误
  • 我还显式地将单元格值转换为long。这样,您就可以在代码中知道您没有使用浮点类型
  • 为了进行比较,我使用了
    Mod
    ,它返回
    N
    的剩余部分除以
    D
    。如果余数为0,则返回true,我们知道没有素数。(注意:余数通常与
    \
    一起使用,它只返回除法结果的整数值。
    Mod
    \
    通常用于整数类型的精确除法,在这种情况下非常合适
  • 最后,我更改了您的消息框,以显示正在比较的实际数字。由于单元格中的数字已转换,因此如果用户输入浮点值,他们可以看到它转换为什么
您可能还会注意到,当您达到数亿个数字时,此代码的运行速度要比您的代码快得多。 "

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

在您的代码行中,
CommandButton1\u Click()
是过程的名称。这很可能是通过向Excel电子表格中添加按钮自动创建的。如果按钮与Excel电子表格绑定,则每次按下按钮时,
CommandButton1\u Click()
都将执行

在您的代码中,
Private
表示过程的范围。
Private
通常意味着不能在过程所在的模块或类之外调用该过程。在我的代码中,我省略了
Private
,因为您可能希望从不同的代码模块调用
GetPrime

您在评论中提到,您必须将我的过程的名称从
GetPrime()
更改为
CommandButton1\u Click()
。这当然有效。但是,您也可以从
CommandButton1\u Click()
中调用
GetPrime
,如下所示:

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

希望这有助于解释一点关于VBA的知识,以加深您的理解!

我看到的最大问题是使用
single
而不是
Integer
Long
。素数是正整数,在十进制值的上下文中不被考虑(据我所知)因此,通过使用单数并将其与整数进行比较,您将面临严重的边缘案例错误

如果N/D=Int(N/D),则行
使用了一种糟糕的方法来判断数字是否为素数。它假设每次除以一个浮点数(在本例中为单)通过除数,如果它有一个十进制余数,那么该余数的整数转换将不相等。然而,在尝试比较答案时,我有时会遇到浮点数字的舍入错误,一般来说,我学会了避免使用浮点到整数的转换作为比较数字的一种方式

以下是一些您可以尝试的代码。请注意:

  • 我改变了N和D的类型,使它们是长的而不是单的。这意味着它们不是浮点型,可能会出现舍入错误
  • 我还显式地将单元格值转换为long。这样,您就可以在代码中知道您没有使用浮点类型
  • 为了进行比较,我使用了
    Mod
    ,它返回
    N
    除以
    D
    的余数。如果余数为0,则返回true,我们知道没有
    Private Sub 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
    
    Option Explicit
    
    Sub GetPrime()
        Dim varValue As Variant
        varValue = Excel.ActiveSheet.Cells(2&, 2&).Value
        If IsNumeric(varValue) Then
            If CLng(varValue) = varValue Then
                If IsPrime(varValue) Then
                    MsgBox varValue & " is prime", vbInformation, "Prime Test"
                Else
                    MsgBox varValue & " is not prime", vbExclamation, "Prime Test"
                End If
                Exit Sub
            End If
        End If
        MsgBox "This operation may only be performed on an integer value.", vbCritical, "Tip"
    End Sub
    
    Public Function IsPrime(ByVal num As Long) As Boolean
        Dim lngNumDiv As Long
        Dim lngNumSqr As Long
        Dim blnRtnVal As Boolean
        ''//If structure is to optimize logical evaluation as AND/OR operators do not
        ''//use short-circuit evaluation in VB.'
        If num = 2& Then
            blnRtnVal = True
        ElseIf num < 2& Then 'Do nothing, false by default.
        ElseIf num Mod 2& = 0& Then 'Do nothing, false by default.
        Else
            lngNumSqr = Sqr(num)
            For lngNumDiv = 3& To lngNumSqr Step 2&
                If num Mod lngNumDiv = 0& Then Exit For
            Next
            blnRtnVal = lngNumDiv > lngNumSqr
        End If
        IsPrime = blnRtnVal
    End Function
    
    Option Explicit
    
    Public Sub Go()
        Dim number As Long
        Dim divisor As Long
        Dim maxdivisor As Long
        Dim isPrime As Boolean
    
        number = CLng(Cells(2, 2))
        Select Case number
            Case Is < 2
                isPrime = False
            Case Is = 2
                isPrime = True
            Case Is > 2
                isPrime = True
                If number mod 2 = 0 Then
                    isPrime = False
                Else
                    maxdivisor = CLng(Sqr(number)) + 1
                    divisor = 3
                    Do
                        If number mod divisor = 0 Then
                            isPrime = False
                            Exit Do
                        End If
                        divisor = divisor + 2
                    Loop While divisor <= maxdivisor
                End If
        End Select
        If isPrime Then
            MsgBox "Number (" & number & ") is prime"
        Else
            MsgBox "Number (" & number & ") is not prime"
        End If
    End Sub