首页 > 解决方案 > vb.net 计算不给出小数

问题描述

您好,我正在尝试进行此计算:[365!/((365 ^ x)((365-x)!))]问题是当我这样做时,它没有给我小数,只是它给我的整数0或 1 因为答案是 0

Public Class Form1
    Private Function fact(ByVal n As Integer) As Numerics.BigInteger
        Dim Z As New Numerics.BigInteger(1)
        For i As Integer = 1 To n
            Z = Z * i
        Next
        Return Z
    End Function

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim min As Integer
        Dim max As Integer
        Dim ranum As Integer
        Dim ind() As Integer
        Dim ran As New Random
        Dim F365 As New Numerics.BigInteger(0)
        F365 = Numerics.BigInteger.Parse("25104128675558732292929443748812027705165520269876079766872595193901106138220937419666018009000254169376172314360982328660708071123369979853445367910653872383599704355532740937678091491429440864316046925074510134847025546014098005907965541041195496105311886173373435145517193282760847755882291690213539123479186274701519396808504940722607033001246328398800550487427999876690416973437861078185344667966871511049653888130136836199010529180056125844549488648617682915826347564148990984138067809999604687488146734837340699359838791124995957584538873616661533093253551256845056046388738129702951381151861413688922986510005440943943014699244112555755279140760492764253740250410391056421979003289600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
        min = Integer.Parse(Tmin.Text)
        max = Integer.Parse(Tmax.Text)
        ranum = Integer.Parse(TRan.Text)
        ReDim ind(ranum)
        For x As Integer = 1 To ranum
            ind(x) = ran.Next(min, max + 1)
            Answer.Items.Add(ind(x))
        Next
        Dim P(ranum) As Numerics.BigInteger
        Dim facts(ranum) As Numerics.BigInteger
        For x = 1 To ranum
            P(x) = 365 ^ (ind(x))
            facts(x) = fact(365 - ind(x))
        Next
        Dim phenB(ranum) As Numerics.BigInteger
        Dim phen(ranum) As Double
        For x = 1 To ranum
            phenB(x) = (P(x) * facts(x))
            phen(x) = F365 / phenB(x)
            tx.Text = phen(x)  (here is the aswer)
        Next

    End Sub
End Class

标签: vb.net

解决方案


BigInteger 类没有为除法提供非整数结果的功能。但是,它确实有BigInteger.Log,因此,使用这些对数恒等式

  • ln(a⋅b) = ln(a) + ln(b)
  • ln(a/b) = ln(a) - ln(b)
  • ln(a^b) = b⋅ln(a)

我们可以像这样进行计算:

Function SomeCalc(n As Integer) As Double
    Dim lnF365 = BigInteger.Log(fact(365))
    Dim lnPower = n * Math.Log(365)
    Dim lnOtherFact = BigInteger.Log(fact(365 - n))

    Return Math.Exp(lnF365 - lnPower - lnOtherFact)

End Function

其中fact()是预先计算的数组:

Option Strict On
Option Infer On
' ... other code ...

Dim fact(365) As BigInteger

' ... other code ...

Private Sub CalcFacts()
    Dim z = BigInteger.One
    For i = 1 To 365
        z *= i
        fact(i) = z
    Next
End Sub

您甚至可以拥有一组预先计算的阶乘日志,而不是一组阶乘。这取决于您是否在其他地方使用它们,以及是否需要它更快一点:

Function SomeCalc(n As Integer) As Double
    Dim lnF365 = lnFact(365)
    Dim lnPower = n * Math.Log(365)
    Dim lnOtherFact = lnFact(365 - n)

    Return Math.Exp(lnF365 - lnPower - lnOtherFact)

End Function

Dim lnFact(365) As Double
' ...
Private Sub CalcLnFacts()
    Dim z = BigInteger.One
    For i As Integer = 1 To largestNum
        z *= i
        lnFact(i) = BigInteger.Log(z)
    Next
End Sub

那个数字 365 应该是一个命名变量——我不知道它会是一个多么明智的名字。


推荐阅读