4

Implement a function that calculates the value of e ^ x, x is a parameter of the function, an integer. To do this, use the Taylor series expansion to calculate the potency of e. The function will receives as a parameter, in addition to the exponent x, the number of terms of the series, which will operate as a maximum value of n. For the resolution of this function, recursion must be used.

I made this:

factorial 0 = 1
factorial n = n * factorial (n-1)

consigna3::Int->Int->Float
consigna3 _ 0 = 1
consigna3 x n = (fromIntegral(x^n) / fromIntegral(factorial n)) + consigna3 x (n-1)

But some results are wrong, this is what I expected:

Ejemplo 1: Main> funcion3 1 1
           2.0
Ejemplo 2: Main> funcion3 1 10
           2.718282
Ejemplo 3: Main> funcion3 2 10
           7.388997
Ejemplo 4: Main> funcion3 10 20
           21991.48
Ejemplo 5: Main> funcion3 10 30
           22026.46
Ejemplo 6: Main> funcion3 0 30
           1.0

The results (10 20) and (10 30) do not match what the function I did returns. What I am doing wrong? Thanks and sorry for my English.

dfeuer
  • 48,079
  • 5
  • 63
  • 167
  • Do you have expected results for `funcion3` involving `10` and smaller values for `n`? I suspect `funcion3` was implemented in a way that is affected less by floating-point rounding error. – chepner Oct 09 '20 at 14:48
  • 2
    `factorial 30` is much larger than the maximum `Int` value. You should be using `Integer` for calculations like these. Also I would suggest `Double` instead of `Float` -- you need all the precision you can get the way you are doing it. – luqui Oct 09 '20 at 14:59
  • this should really be calculated in `Rational`s. use the code in the accepted answer but replace `/` with `%`. convert only the final result to a floating point number, with `fromRational`. – Will Ness Jul 16 '21 at 16:00

1 Answers1

4

You are using Int for calculations that will overflow an Int. Instead, convert to Float right away, and then using Float for everything. So:

consigna3 x n = ((fromIntegral x)^n / factorial (fromIntegral n)) + consigna3 x (n-1)

There are two critical changes from Int to Float here: first, you do x^n where x :: Int, but I do fromIntegral x^n where fromIntegral x :: Float; second, you do factorial n where n :: Int, but I do factorial (fromIntegral n) where fromIntegral n :: Float.

Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380