Search code examples
scalafactorial

what's wrong in this factorial function (from book : programming in scala)?


here is the factorial function found in Programming in Scala Book :

// factorial function
def factorial(x: BigInteger): BigInteger =
  if (x==BigInteger.ZERO) 
    BigInteger.ONE 
  else 
    x.multiply(factorial(x.subtract(BigInteger.ONE)))

i call it from my main function :

// using factorial function
factorial(8)

in scala IDE, i got "type mismatch" error...

Could you tell me what's wrong in these lines ?

Thanks for your help :-)


Solution

  • You had better use BigInt. Do not use BigInteger. I know why you used BigInteger is that there is an example in the book using BigInteger, anyway.

    BigInt and BigDecimal (in scala.math package) are for Scala. BigInteger and BigDecimal (in java.math package) are for Java. Scala also can use BigInteger and java.math.BigDecimal, but they are not optimized for Scala. Implicit conversions may not work for them. (For example, Int to BigInteger is not automatically processed)

    If you want to use BigInteger anyway, you can call the function by

    factorial(BigInteger.valueOf(8)) // Long to java.math.BigInteger
    

    or

    factorial(new BigInteger("8")) // String to java.math.BigInteger
    

    However, if you use BigInt of Scala, the code gets much simpler.

    // factorial function
    def factorial(x: BigInt): BigInt =
      if (x == 0) 
        1
      else 
        x * factorial(x - 1)
    

     

    // using factorial function
    factorial(8)
    

    Since x or return type of factorial() is already BigInt, multiplication with x or factorial() results in BigInt not Int, which prevents overflow. BigInt also supports operator overloading (in this case operator * and -), which is not in Java.


    Also, you can define an even simpler factorial function in Scala.

    def factorial(x: BigInt): BigInt = (BigInt(1) to x).product