# Calculate e^x and ln(x)

Given a floating point x (x<100), return e^x and ln(x). The first 6 decimal places of the number have to be right, but any others after do not have to be correct.

You cannot have any "magic" constants explicitly stated (e.x. a=1.35914 since 1.35914*2 ~= e), but you can calculate them. Only use +, -, *, and / for arithmetic operators.

If x is less than or equal to 0, output ERROR instead of the intended value of ln(x).

Test Cases:

input: 2
output: 7.389056 0.693147
input: 0.25
output: 1.284025 -1.386294
input: 2.718281828
output: 15.154262 0.999999  (for this to output correctly, don't round to 6 places)
input: -0.1
output: 0.904837 ERROR


Shortest code wins.

• I assume you mean to exclude exponentiation of entirely (not just for the the calculation of e itself)? 2**(x*1.442695) for example seems a bit too easy. – primo Nov 25 '12 at 18:04
• @primo: yes, there is no exponentiation whatsoever, but things like product([2]*3) is ok. I guess I should rule out "magic constants" in the case of 1.442695. – beary605 Nov 25 '12 at 18:35
• You might want to also specify a valid range for the input - any approximation can lose accuracy if x becomes too large or too small. – arshajii Nov 26 '12 at 0:08
• @A.R.S.: added a boundary. Thanks. – beary605 Nov 26 '12 at 0:14
• No one uses APL!? Seriously? – TwiNight Dec 25 '12 at 19:45

## JavaScript, 103101999793 90

This implementation is based on primo's comprehensive description of the algorithm he used.

for(e=l=x=prompt(g=1e5);--g;y=x-1,l=(x>1?y/=x:-y)*l+y/g)
e=1+e/g*x;


Edit:
- Trying to catch Perl. Stole a byte back from primo by copying his branch. :)
- 2 more bytes courtesy of primo.
- Finally, caught primo's version! With primo's help, of course... :)
- Simplified the assignment to L. Shaved 3 more bytes.

• It's somewhat humorous that defining Math.abs inline is actually shorter than using the built-in. – primo Nov 27 '12 at 7:39
• As far as catching perl goes, would it help if I pointed out that the initial values of e and l don't really matter? – primo Dec 2 '12 at 6:58
• @primo Nice catch! – Paul Walls Dec 2 '12 at 8:13
• I've got 93, by combining the y and l definitions: l=(x>1?y=1-1/x:-(y=x-1))*l+y/g – primo Dec 14 '12 at 7:29
• Very elegant. I probably spent over an hour trying to figure out a way to exploit the relationship between x<1 and y<0. You sir, are a genius! :) – Paul Walls Dec 14 '12 at 9:37

## PHP 109 107 bytes

<?for($g=1e4;--$g;$l=$y/$g+abs($y=$x>1?1-1/$x:$x-1)*$l)$e=1+$e/$g*$x.=fgets(STDIN);echo"$e ",$x>0?$l:ERROR;  is a fairly straight-forward calculation. I use a nested form of the sum of inverse factorials, which not only increases the convergence rate, but also allows for exponentiation at the same time: is slightly more complicated. All convergent series seem to work for or , but not both (Newton's iteration does not have this limitation, but requires the calculation of each step). This isn't really a problem, though, given the log identity: This means that if, for example, the iteration you're using only works on and , you can use the multiplicative inverse of and negate the result. Because I was using a nested identity for , I also chose to use a nested identity for : where Or equivalently, as demonstrated by Paul Walls' implementation: I define the case as (which is necessarily negative), using the absolute value for the inner product, and then allowing a bare value in the fraction to correct the sign. Sample I/O: $ echo 2 | php exp_ln.php
7.3890560989307 0.69314718055995

$echo 0.25 | php exp_ln.php 1.2840254166877 -1.3862943611199$ echo 2.718281828 | php exp_ln.php
15.154262234523 0.99999999983113

$echo -0.1 | php exp_ln.php 0.90483741803596 ERROR  ## Perl 9593 89 bytes $e=1+$e/$?*($x.=<>),$l=$_/$?+$l*abs,$_=$x>1?1-1/$x:$x-1while--$?;print"$e ",$x>0?$l:ERROR  Nearly identical to the PHP solution above, with a slightly larger iteration (65535 down to 0). Edits: • Both 2 byte improvements due to Paul Walls. • Four more bytes saved in Perl by (ab)using $?, which is stored internally as an unsigned short, and by using $_ to save parentheses in abs. • For x = 1e-4, I get php "1.0001000050002 -8.9909564381939" and perl "1.00010000500017 -8.99099322429857". Should be like "1.000100005 -9.21034037195" Anyways nice job taking advantage of ln x = -ln 1/x to use a nested expression – miles Nov 26 '12 at 13:49 • @milest x=1e-5 will be off by even more, because it's the same calculation as x=100000. As it is, x=1e-2 and x=100 are accurate to full floating point precision, and x=1e-3 and x=1000 are accurate to about 5 digits. If more accuracy is needed, the arbitrary 1e4 bound that I've chosen can be increased accordingly. – primo Nov 26 '12 at 14:25 ## Haskell, 166 (89 without I/O) s=1e-7 e x|x>s=1/e(-x)|x>0=1+x|y<-e$x+s=y-y*s
l x|x<1=0-l(1/x)|1>0=sum$map(s/)[1,1+s..x] n x|x<0="ERROR"|1>0=show$l x
main=interact$unwords.(\x->[show$e x,n x]).read


Takes an alternative approach: we use that

∂/∂x ex = ex

and solve the differential equation numerically, with a simple euler method. Similarly, use

ln x = 1x 1/x d‌x

and calculate the integral with the rectangular method.

Example:

$echo 2 | ./exp-and-log 7.389056835370484 0.6931472554471929$ echo 0.25 | ./exp-and-log
1.284025432730133 -1.3862944228194163
$echo 2.718281828 | ./exp-and-log 15.15426430695358 1.0000000576151333$ echo -0.1 | ./exp-and-log
0.9048374135134576 ERROR

It's quite amazingly inefficient, in fact it uses about 4 GB of memory even for these examples (since it's non-tail–recursive... you need to compile (in GHC) with -with-rtsopts=-K2G so it even accepts such a ridiculous stack size).

## Python 2 (168 char)

basic implementation of power series

I need to learn a golfing language =/

I increased the bound to 1e-14 (twice from 1e-7) since some values were off a bit in 6 decimal places, works well for input from 1e-5 to 100 (slows down at input approaches 0)

x=input();t,r,i=1,0,1.
while abs(t)>=1e-14:t,r,i=t*x/i,r+t,i+1
if x<=0:s='Error'
else:z=(x-1.)/(x+1);t,s,i=2*z,0,1
while abs(t/i)>=1e-14:t,s,i=t*z*z,s+t/i,i+2
print r,s

• Doesn't python support m=1e-7? – dmckee Nov 25 '12 at 20:53
• yes it does but 1e-7 can be thought of as 1*10^-7 which might be thought of as exponentiation, so I'm not really sure if its allowed here – miles Nov 25 '12 at 20:59
• I will allow for scientific notation. – beary605 Nov 26 '12 at 0:02