Answered by:
Birthday Paradox Calculator

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 TI84 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 Label1.Text = BirthdayParadox(TextBox1.Text) End Sub End Class
Thanks, Jordan
If you find an answer helpful, click the Helpful button. If you find an answer to your question, mark it as the answer.
www.metasdevelopment.com Jordan St. Godard  Microsoft Community Contributor © 2011Helpful Links:
 Edited by Jordan St. Godard Wednesday, November 09, 2011 8:29 PM
Question
Answers

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...") Console.ReadLine() End Sub
I'm not sure you will be able to divide big integers and get a double result.
Chris
 Marked as answer by Jordan St. Godard Wednesday, November 09, 2011 9:31 PM

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...") Console.ReadLine() 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...") Console.ReadLine() End Sub End Module
 Edited by Devon_NullmanMicrosoft community contributor Thursday, November 10, 2011 2:01 AM
 Marked as answer by Jordan St. Godard Thursday, November 10, 2011 12:09 PM
All replies


No? Never heard of it until now. How do I use it?
If you find an answer helpful, click the Helpful button. If you find an answer to your question, mark it as the answer.
www.metasdevelopment.com Jordan St. Godard  Microsoft Community Contributor © 2011Helpful Links:

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...") Console.ReadLine() End Sub
I'm not sure you will be able to divide big integers and get a double result.
Chris
 Marked as answer by Jordan St. Godard Wednesday, November 09, 2011 9:31 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 !

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 Label1.Text = BirthdayParadox(30.0#) End Sub End Class
Success
Cor 
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/enus/library/system.numerics.aspx
http://msdn.microsoft.com/enus/library/system.numerics.biginteger.aspx
Chris:
I didn't think of doing it that way. Thanks!
Thanks again,
 Jordan
If you find an answer helpful, click the Helpful button. If you find an answer to your question, mark it as the answer.
www.metasdevelopment.com Jordan St. Godard  Microsoft® Community Contributor 2011Helpful Links:

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...") Console.ReadLine() 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...") Console.ReadLine() End Sub End Module
 Edited by Devon_NullmanMicrosoft community contributor Thursday, November 10, 2011 2:01 AM
 Marked as answer by Jordan St. Godard Thursday, November 10, 2011 12:09 PM

Thanks for the correction. I revisited 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?
 Edited by Chris Dunaway Thursday, November 10, 2011 2:39 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/cgibin/birthday and the code from above.
 Jordan
If you find an answer helpful, click the helpful button. If you find an answer to your question, mark it as the answer.Jordan St. Godard  Microsoft® Community Contributor 2011
Meta's Development
Helpful Links:
 Edited by Jordan St. Godard Thursday, November 10, 2011 3:47 PM

