davedelong / DDMathParser

String → Number
MIT License
856 stars 153 forks source link

Factorial of Double greater than Int.max causes fatal error #113

Closed graycampbell closed 7 years ago

graycampbell commented 8 years ago

In Double.swift, in the factorial function, the line let arg1Int = Int(self) breaks with the error message "fatal error: floating point value can not be converted to Int because it is greater than Int.max" if trying to get the factorial of a number greater than Int.max.

I got it to work by just adding an extra condition to the first if statement instead to make sure self is less than or equal to Int.max:

func factorial() -> Double {
    if Darwin.floor(self) == self && self > 1 && self <= Double(Int.max) {
        // it's an integer
        let arg1Int = Int(self)

        if self <= Double(Int.largestIntegerFactorial) {
            return Double((1...arg1Int).reduce(1, combine: *))
        } else {
        // but it can't be represented in a word-sized Int
            var result = 1.0
            for var i = self; i > 1; i-- {
                result *= i
            }
            return result
        }
    } else {
        return tgamma(self+1)
    }
}

I am curious though - how does that affect the self+1 in return tgamma(self+1)? My guess would be that it doesn't matter since "the factorial of some Int greater than Int.max" and "the factorial of some Int greater than Int.max plus one" are both going to be infinity anyway, right?