vb.net - 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
解决方案
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 应该是一个命名变量——我不知道它会是一个多么明智的名字。
推荐阅读
- haskell - fmap 在 Nothing 上的 2-arity 函数应该返回 Nothing?
- python - 如何从传递给多处理的函数返回计数器字典?
- jquery - 如何使用 handlebarsjs 渲染 Boostrap 模板
- json - Lagom:事件在 cassandra 中没有 json 序列化
- vim - vimrc 设置不是在开始时应用,而是在采购之后应用
- amazon-web-services - AWS S3 存储桶访问控制
- css - react.js 媒体查询和轮播
- bash - 带有 +30 个别名的鱼壳列表
- javascript - 在鼠标悬停时选择单个链接
- c++ - C++ 中的抽象类帮助