Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factorials in Swift

I need a good factorial function. The one I have written here works entirely, except when n gets far too large. This is for a calculator app, and I can return 0 / 0 for values that cannot be factorialed because I have an error checker that will declare that as impossible. However performing the function on a very large number crashes the app. I can't use a range operator because my types are doubles.

func factorial(n: Double) -> Double {
    if n >= 0 {
        return n == 0 ? 1 : n * self.factorial(n - 1)
    } else {
        return 0 / 0
    }
}

What is the best way to do this?

like image 587
modesitt Avatar asked Mar 15 '23 15:03

modesitt


1 Answers

As others have said you can use libraries that support larger numbers, or just don't allow values that are too big.

Note that if you want to handle very large values you might need to use a loop rather than a recursive algorithm because recursion can cause a Stack Overflow. Yes, that's right, an SO "eponymous crash".

To prevent numbers that are too big, figure out the largest number that doesn't crash, and do input checking and reject numbers bigger than that.

You can figure out the number that crashes it by going in the opposite direction and logging the count and the result every 10 steps:

1 * 2 * 3 * 4 * 5 * 6...

When you crash, go back to the previous largest logged value, start from there plugging in your previously logged factorial result, and step 1 at a time until you crash. Then only allow n that's 1 less than your crash value.

like image 164
Duncan C Avatar answered Mar 27 '23 13:03

Duncan C