| Bytes | Lang | Time | Link |
|---|---|---|---|
| 057 | APLNARS | 250213T121150Z | Rosario |
| 090 | Mathematica | 130512T221909Z | Kaya |
| 036 | APL | 130513T165908Z | marinus |
| 050 | JavaScript | 130512T152927Z | Greg |
| 057 | Python | 130510T071305Z | Keith Ra |
| 069 | C | 130509T222913Z | Johannes |
APL(NARS), 57 chars
r←f w;e;i;t;y
(y e)←w⋄r←i←1-t←1
r+←t⋄→2×⍳e<∣t×←y÷i+←1
r+←t
//14+18+21+4=57
I copy algo from https://codegolf.stackexchange.com/a/11625/120560. From calculator this result e^4 with enought digits:
54,59815003314423907811026120286
test:
f 4 0.00001
54.59814948
f 4 0.00001
54.59814948
f 4 0.000001
54.59814993
f 4 0.0000001
54.59815001
Mathematica, 90
f[x_,p_]:=Piecewise[{{Sum[x^i/i!,{i,0,50}],x>0},{1/Sum[(-x)^i/i!,{i,0,50}],x<0},{1,x==0}}]
I also ignore the precision p and assume that 20 decimal points will be the most accuracy desired. It also works for negative values of x! To be worked on more later.
Python, 88
def E(x,p):
t=n=s=1.;y=x
if x<0:y=-x
while t:t*=y/n;n+=1;s+=t
if x<0:s=1/s
return s
Why the Power Series approach does not work without cases:
The issue with the taylor series for e(x) centered at the origin is that it is alternating for negative x. When the distance from the origin is small, say x= -1 or -2 then this is not an issue as we get convergence to 20 decimal places after about 20-30 terms of the power series. However when the distance from the origin grows all hell breaks loose. Observe the pattern for x= -1 where f[x,n] refers to the taylor series with n+1 terms.
Exp[-20] = 2.0611536224385578280*10^-9
f[-20,1] = -19.000000000000000000
f[-20,2] = 181.00000000000000000
f[-20,3] = -1152.3333333333333333
f[-20,4] = 5514.3333333333333333
...
f[-20,10] = 1.8596236807760141093*10^6
f[-20,15] = -1.4140053694562736891*10^7
f[-20,20] = 2.1277210342544299144*10^7
f[-20,30] = 1.5996940964229284082*10^6
f[-20,40] = 4442.0343631250907290
f[-20,50] = 1.0469169720658217252
f[-20,60] = 0.000034317328370370852087
f[-20,70] = 2.2782871646157681977*10^-9
It takes until term 70 to get within .000000001 of the true value, and I was being kind using x= -20. If we try numbers as low as x= -500 we are more than 10^200 off at term 500. Now lets see, what are we even working with at this point, iteration 500, this should include the term x^500/500!. 500! if of the order 10^1134, but python and other programming languages are not equipped to deal with numbers much larger than 2^63 as integers or 10^308 for doubles (unless you have some sort of arbitrary precision library...?)
APL (36)
{x t←⍺⍵⋄0{t>i←(x*⍵)÷!⍵:⍺⋄∇/⍺⍵+i 1}0}
The left argument is the number and the right argument is the tolerance, i.e.
4 {x t←⍺⍵⋄0{t>i←(x*⍵)÷!⍵:⍺⋄∇/⍺⍵+i 1}0} 0.00001
54.59814722
It uses a power series expansion.
Explanation:
x t←⍺⍵: store the left argument (x) inxand the right argument (tolerance) int0{...}0: iterator function,⍺is the accumulator and⍵is the iterationt>i←(x*⍵)÷!⍵: calculate the current iteration's value, and see if it is higher than the tolerance:⍺: if so, return the accumulator⋄∇/⍺⍵+i 1: if not, increment the accumulator byiand the iteration by1and try again.
JavaScript, 50 Chars
Given that javascript has variable args support, this will work with the input e(4,0.00001). Otherwise, it would be 52 chars.
function e(x){for(t=n=s=1;t*=x/n++;s+=t);return s}
If it is going to factor in the precision as the problem states, it can be done in 56 chars.
function e(x,p){for(t=n=s=1;(t*=x/n++)>p;s+=t);return s}
Python, 59 57 chars
def E(x,p):
t=n=s=1.
while t:t*=x/n;n+=1;s+=t
return s
Uses the power series expansion of e^x. Ignores p and just calculates the result to full double precision.
C, 88 69
double e(int e, double l) {double a,p=1,i=0,f=1,r=1;while ((a=(p*=e)/(f*=++i))>l) r+=a;return r;}
double e(int x, double l) {double i=0,t=1,r=1;while (t*=x/++i) r+=t;return r;}
call e. if you change the first argument to e from int to double, it will even work for floating point exponents.
Code counted without any white space or comments.
Edited some ideas from Keith into it (combine p and f into t, ignore l).
Yes, power series is the way to go. Sure, once one got the idea, everyone copy it.