帕斯卡三角形给出 13 的溢出

pascal triangle gives overflow for 13

我在多行教科书中写了一段输出帕斯卡三角形的代码。该程序适用于 1 到 12 之间的输入,但一旦输入值 13 就会出现溢出错误。

我是否可以进行任何修改以使程序能够准确地给出 13 和更高的输出?

这是我使用的代码:

Public Class pascal_triangle

    Private Function factorial(ByVal k As Integer) As Integer
        If k = 0 Or k = 1 Then
            Return 1
        Else
            Return k * factorial(k - 1)
        End If
    End Function


    Private Sub BtnGen_Click(sender As Object, e As EventArgs) Handles BtnGen.Click
        Dim nCr As Integer
        Dim i, j, k As Integer
        Dim output As String

        output = ""

        j = Val(TxtColumn.Text)

        For k = 0 To j
            For i = 0 To k
                Dim fact, fact1, fact2 As Integer

                fact = factorial(k)
                fact1 = factorial(k - i)
                fact2 = factorial(i)
                nCr = fact / (fact1 * fact2)
                TxtOutput.Text += Str(nCr) & output
            Next
            TxtOutput.Text += vbCrLf
        Next
    End Sub

End Class

溢出是因为 13! 太大而不适合一个整数。

可表示的最大 integer(32 位有符号)是

  • 2147483647(0x7FFFFFFF == 01111111 11111111 11111111 11111111b)

所以 :

 12!    =  479001600  
 MaxInt = 2147483647
 13!    = 6227020800    

如果您想使用比这更大的数字,您需要使用更大的数字类型。下一个较大的类型是 Long(64 位有符号,最大 9223372036854775807)或者,为了您的目的,ULong(无符号 64 位,因为您不需要负数,这是 18446744073709551615) 的两倍。

这将使您计算到 20!,即 2432902008176640000。对于大于此的数字,您需要考虑使用 BigInteger 或其他允许保存和计算任意大数字的专用库。

或者,您可以查看其他计算任意行的方法 without using factorials

您的主要问题是您使用的 Integer 太小而无法容纳 13 的阶乘。将您的阶乘函数更改为 return Long。将 Option Strict On 变为 nCr 也是一个好主意 Double.

Private Function factorial(ByVal k As Integer) As Long
    If k = 0 Or k = 1 Then
        Return 1
    Else
        Return k * factorial(k - 1)
    End If
End Function

Private Sub BtnGen_Click(sender As Object, e As EventArgs) Handles BtnGen.Click
    Dim nCr As Double
    Dim i, j, k As Integer
    Integer.TryParse(TxtColumn.Text, j)
    For k = 0 To j
        For i = 0 To k
            Dim fact, fact1, fact2 As Long
            fact = factorial(k)
            fact1 = factorial(k - i)
            fact2 = factorial(i)
            nCr = fact / (fact1 * fact2)
            TxtOutput.Text += nCr.ToString & " "
        Next
        TxtOutput.Text += vbCrLf
    Next
End Sub