• Wednesday, November 09, 2011 8:28 PM

With the information I've found from the birthday paradox, I'm trying to make a calculator similar to this but I cannot seem to figure out how to get a real number. The factorial of 365! gives an overflow. But it's not just VB, even my TI-84 Plus Silver Edition calculator gives an overflow as the number is so high.

• What data types can I use to get numbers as high as "365!"?
• Is there anyway I can get an accurate answer for the birthday paradox calculator in VB.NET?
```'Option Strict On

Public Class Form1

Private Function BirthdayParadox(ByVal people As Integer) As String
' P(A) prime
Dim birthday As Decimal

birthday = CDec((Factorial(365) / (Factorial(365 - people) * Math.Pow(365, people))))

Dim output As Decimal
output = (1 - birthday)

Return output.ToString()

End Function

Public Function Factorial(ByVal Number As Decimal) As Decimal
If Number = 0 Then
Return 1
Else
Return Number * Factorial(Number - 1)
End If
End Function

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
End Sub
End Class

```

Thanks,

- Jordan

www.metasdevelopment.com Jordan St. Godard | Microsoft Community Contributor © 2011

### All Replies

• Wednesday, November 09, 2011 8:55 PM

Have you tried BigInteger?
Serial Port      Random      Microsoft® Community Contributor 2011
• Wednesday, November 09, 2011 8:55 PM

No? Never heard of it until now. How do I use it?
www.metasdevelopment.com Jordan St. Godard | Microsoft Community Contributor © 2011

• Wednesday, November 09, 2011 9:22 PM

The link to the calculator link you posted show how they arrive at their conclusion:

365/365 + 364/365 + 363/365 + 362/365 + ... + 336/365

So you can use an iterative approach:

```    Sub Main()
Dim numberOfPeople As Integer = 30
Dim total As Double = 0.0

For x As Integer = 0 To numberOfPeople
total += CDbl(365 - x) / 365.0
Next

Console.WriteLine("Odds are {0} percent", 100.0 - total)

Console.WriteLine("Press ENTER to exit...")
End Sub
```

I'm not sure you will be able to divide big integers and get a double result.

Chris

• Wednesday, November 09, 2011 9:24 PM

Jordan,

Apart from the question of the data type you need to use, I would try to simplify the calculation. Inded, 365! is such a huge number, it will cause overflow in any situation.

Rather, I'd like to convince you that :

365! / (365 - people)!

is probably a lesser number, that can be easier to compute:

365! / (365 - people)!  = 365*364*363 .... ("people" times)

So if "people" is  a fairly low number, your computation won't overflow !

• Wednesday, November 09, 2011 9:25 PM

Jordan,

Even if I use a double I get an error, but then a stackoverflow. I think it is in your case just a complex of that, for me it seems more that your recursive loop is somehow to endless or complex.

```Public Class Form1
Private Function BirthdayParadox(ByVal people As Double) As String
' P(A) prime
Dim birthday = Factorial(365.0#) / Factorial(365.0# - people * Math.Pow(365.0#, people))
Dim output = (1.0# - birthday)
Return output.ToString()
End Function
Public Function Factorial(ByVal Number As Double) As Double
If Number = 0 Then
Return 1
Else
Return Number * Factorial(Number - 1.0#)
End If
End Function
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
End Sub
End Class
```

Success
Cor
• Wednesday, November 09, 2011 9:35 PM

Sygrien:

People is the parameter; I can't say that people will be a low number.

dbasnett:

Figured out bigInt. Thanks for the suggestion!

http://msdn.microsoft.com/en-us/library/system.numerics.aspx

http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx

Chris:

I didn't think of doing it that way. Thanks!

Thanks again,

- Jordan

www.metasdevelopment.com Jordan St. Godard | Microsoft® Community Contributor 2011

• Thursday, November 10, 2011 1:52 AM

The code example given:

```    Sub Main()
Dim numberOfPeople As Integer = 30
Dim total As Double = 0.0

For x As Integer = 0 To numberOfPeople
total += CDbl(365 - x) / 365.0
Next

Console.WriteLine("Odds are {0} percent", 100.0 - total)

Console.WriteLine("Press ENTER to exit...")
End Sub

```

If you change 30 to 23, you get 76.75%, when according to what I have read, 23 is the point at which it should be 50%

If you change 30 to 366, you get -82%

Try this

```Module Module1
Function different_birthdays(ByVal n As Integer) As Double
If n = 1 Then
Return 1
Else
Return different_birthdays(n - 1) * (365.0 - (n - 1)) / 365.0
End If
End Function
Sub Main()
Dim numberOfPeople As Integer = 23
Dim total As Double = different_birthdays(numberOfPeople)
Console.WriteLine("Odds are {0} percent", (1 - total) * 100)
Console.WriteLine("Press ENTER to exit...")
End Sub
End Module
```

• Thursday, November 10, 2011 2:35 PM

Thanks for the correction.  I re-visited my approach and noticed where the problem lie.  I was using addition (+=) instead of multiplication (*=), but I like your recursive approach better.

And naturally, if there are more than 365 people, the odds are 100 percent that two would have the same birthday.  But I wonder, what should be the correct return value if there is only one person?  Should it be 100% ?  Or is it undefined?

• Thursday, November 10, 2011 2:47 PM

And naturally, if there are more than 365 people, the odds are 100 percent that two would have the same birthday.  But I wonder, what should be the correct return value if there is only one person?  Should it be 100% ?  Or is it undefined?

If one person 0%. Tested it with http://jeff.aaron.ca/cgi-bin/birthday and the code from above.

- Jordan

Jordan St. Godard | Microsoft® Community Contributor 2011
Meta's Development

• Thursday, November 10, 2011 5:47 PM

It's probably worth adding the else if people > 365 return 100 so that you don't get stack overflow errors if someone puts in 1500 or something.  (And so that you don't get more than 100% as a result.)
• Thursday, November 10, 2011 5:57 PM

Up to and including 11193 people, you get 100%

11194 and on, overflow