How to calculate the Factorial of Numbers > 170
chem1
09-02-2004, 02:49 PM
Hi,
The calculators which come with various Operating Systems can evaluate the factorials of numbers way high than 170. For example, the Win XP Calculator can even give you an answer of 10000! :D
Any idea how this can be implemented in FORTRAN or C or VB .NET
Thankx in advance...
The gamma function (more precisely, the natural logarithm of gamma) routine in NR should do the trick, although since the factorials tend to be on the big side around 170, you might have to convert the routines manually to support big numbers.
Anyway, in case you don't know, gamma and the factorial are related by gamma(n+1) = n! . See this link (http://mathworld.wolfram.com/GammaFunction.html) for more info.
Hope this helps.
Jan M. (^_^)
P.S. If you aren't that satisfied with the NR routine, you might want to check Viktor Toth's site (http://rskey.org/lanczos.htm). He has an arbitrary-precision implementation in C++.
chem1
09-07-2004, 12:37 PM
Thanks for the reply. I have two questions here:
1) What do you mean when you say:
.you might have to convert the routines manually to support big numbers.
2) I implemented the Sinh Formula at Viktor's site but still I am unable to calculate factorials of anything above 170. Of course the reason is that the data type I am using is .NET's Double which will only support powers upto +308; hence the calculation overflows
Any ideas?
Thanx in advance....
The second point you mentioned was what I exactly meant. The usual double precision data type is ill-equipped to handle numbers of that magnitude. I am not very keen on the data types in .NET, but are there any other data types that can repesent numbers of large magnitude in that language?
Jan M. (^_^)
chem1
09-08-2004, 02:36 PM
I am having some success using the java.math.BigInteger class available in .NET. I will let you know as soon as I get some working code
Thankx for all your help :D
chem1
09-08-2004, 04:39 PM
Here is the first shot at it in VB .NET. It is slow but it works. I am still working to optimize it
Public Function BigFactorial(ByVal val As Double) As String
Dim retVal As New java.math.BigInteger("1") 'initialize the BigInteger variable
Dim num1 As New java.math.BigInteger("1") 'initialize the BigInteger variable
Dim SimpleFactorial As Double
If val < 171 Then 'Simple factorial...Double can handle it so send it to the Factorial Subroutine
SimpleFactorial = Factorial(val)
Return SimpleFactorial.ToString
Else
Try
Dim temp As Double = num1.doubleValue 'define the For Loop variable
For temp = 1 To val
retVal = retVal.multiply(num1.valueOf(CLng(temp))) 'Calculate the Factorial
Next
Return FormatBigInteger(retVal.toString)
Catch ofe As OverflowException
End Try
End If
End Function
Private Function FormatBigInteger(ByVal BigInt As String) As String
Dim varLengthBeyondDouble As Double
Dim ConvertedDouble As Double
'308 is the max power which a double can hold , so determine how many
'decimal places we missed beyond the 308 mark
varLengthBeyondDouble = BigInt.ToString.Length - 308
ConvertedDouble = CDbl(BigInt.ToString.Substring(0, 308)) 'take the first 308 characters a convert to double
Dim Exponent As Double
Dim Split() As String
Dim ReturnValue As String
Exponent = CDbl(ConvertedDouble.ToString.Substring(ConvertedD ouble.ToString.IndexOf("+"))) 'extract the current exponent value
Exponent = Exponent + varLengthBeyondDouble 'Evaluate the new exponent depending on how many places beyond 308 are there
Split = ConvertedDouble.ToString.Split("E"c) 'Split the original number
ReturnValue = Split(0).ToString & "E+" & Exponent 'append the new exponent
Return ReturnValue 'return the formatted value
End Function
chem1
09-09-2004, 12:07 PM
Public Function BigFactorial(ByVal val As Integer) As String
Dim retVal As New java.math.BigInteger("1") 'initialize the BigInteger variable
Dim SimpleFactorial As Double
If val < 171 Then 'Simple factorial...Double can handle it so send it to the Factorial Subroutine
SimpleFactorial = Factorial(val)
Return SimpleFactorial.toString
Else
For temp As Long = 1 To val 'The valueOf method for BigInteger requires Long data Type
retVal = retVal.multiply(java.math.BigInteger.valueOf(temp) ) 'Calculate the Factorial
Next
Return FormatBigInteger(retVal.toString)
End If
End Function