'How to calculate the 21! (21 factorial) in swift?

I am making fuction that calculate factorial in swift. like this

func factorial(factorialNumber: UInt64) -> UInt64 {
    if factorialNumber == 0 {
        return 1
    } else {
        return factorialNumber * factorial(factorialNumber - 1)
    }
}

let x = factorial(20)

this fuction can calculate untill 20.

I think factorial(21) value bigger than UINT64_MAX.

then How to calculate the 21! (21 factorial) in swift?



Solution 1:[1]

Unsigned 64 bit integer has a maximum value of 18,446,744,073,709,551,615. While 21! = 51,090,942,171,709,440,000. For this kind of case, you need a Big Integer type. I found a question about Big Integer in Swift. There's a library for Big Integer in that link.

BigInteger equivalent in Swift?

Solution 2:[2]

func factorial(_ n: Int) -> Double {
  return (1...n).map(Double.init).reduce(1.0, *)
}
  1. (1...n): We create an array of all the numbers that are involved in the operation (i.e: [1, 2, 3, ...]).

  2. map(Double.init): We change from Int to Double because we can represent bigger numbers with Doubles than with Ints (https://en.wikipedia.org/wiki/Double-precision_floating-point_format). So, we now have the array of all the numbers that are involved in the operation as Doubles (i.e: [1.0, 2.0, 3.0, ...]).

  3. reduce(1.0, *): We start multiplying 1.0 with the first element in the array (1.0*1.0 = 1.0), then the result of that with the next one (1.0*2.0 = 2.0), then the result of that with the next one (2.0*3.0 = 6.0), and so on.

Step 2 is to avoid the overflow issue.

Step 3 is to save us from explicitly defining a variable for keeping track of the partial results.

Solution 3:[3]

Did you think about using a double perhaps? Or NSDecimalNumber?

Also calling the same function recursively is really bad performance wise.

How about using a loop:

let value = number.intValue - 1

var product = NSDecimalNumber(value: number.intValue)

for i in (1...value).reversed() {
    product = product.multiplying(by: NSDecimalNumber(value: i))
}

Solution 4:[4]

Here's a function that accepts any type that conforms to the Numeric protocol, which are all builtin number types.

func factorial<N: Numeric>(_ x: N) -> N {
    x == 0 ? 1 : x * factorial(x - 1)
}

Solution 5:[5]

First we need to declare temp variable of type double so it can hold size of number.
Then we create a function that takes a parameter of type double.
Then we check, if the number equal 0 we can return or do nothing. We have an if condition so we can break the recursion of the function. Finally we return temp, which holds the factorial of given number.

var temp:Double = 1.0

func factorial(x:Double) -> Double{
    if(x==0){
        //do nothing
    }else{
        factorial(x: x-1)
        temp *= x
    }
    return temp
}

factorial(x: 21.0)

Solution 6:[6]

If you are willing to give up precision you can use a Double to roughly calculate factorials up to 170:

func factorial(_ n: Int) -> Double {
    if n == 0 {
        return 1
    }
    var a: Double = 1
    for i in 1...n {
        a *= Double(i)
    }
    return a
}

If not, use a big integer library.

Solution 7:[7]

func factoruial(_ num:Int) -> Int{
        if num == 0 || num == 1{
            return 1
        }else{
           return(num*factoruial(num - 1))
       }
   }

Solution 8:[8]

I make function calculate factorial like this:

func factorialNumber( namber : Int ) -> Int {
    var x = 1
     
    for i in 1...namber {
        x *= i   
    }
    return x 
            
}
print ( factorialNumber (namber : 5 ))

Solution 9:[9]

Using recursion to solve this problem:

    func factorial(_ n: UInt) -> UInt {
        return n < 2 ? 1 : n*factorial(n - 1)
    }

Solution 10:[10]

func factorial(a: Int) -> Int {

    return a == 1 ? a : a * factorial(a: a - 1)
}

print(factorial(a : 5))

print(factorial(a: 9))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2
Solution 3
Solution 4 Peter Schorn
Solution 5 Yunnosch
Solution 6 Luuk Berkers
Solution 7 Pavnesh Singh
Solution 8 Tyler2P
Solution 9 Hunter 19
Solution 10 4b0