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...

jaje
09-06-2004, 11:16 AM
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....

jaje
09-08-2004, 08:00 AM
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