帕斯卡三角形给出 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
我在多行教科书中写了一段输出帕斯卡三角形的代码。该程序适用于 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