89 lines
1.4 KiB
CoffeeScript
89 lines
1.4 KiB
CoffeeScript
# Natural logarithm.
|
|
#
|
|
# Note that we use the mathematics / Javascript / Mathematica
|
|
# convention that "log" is indeed the natural logarithm.
|
|
#
|
|
# In engineering, biology, astronomy, "log" can stand instead
|
|
# for the "common" logarithm i.e. base 10. Also note that Google
|
|
# calculations use log for the common logarithm.
|
|
|
|
|
|
Eval_log = ->
|
|
push(cadr(p1))
|
|
Eval()
|
|
logarithm()
|
|
|
|
logarithm = ->
|
|
save()
|
|
yylog()
|
|
restore()
|
|
|
|
yylog = ->
|
|
d = 0.0
|
|
|
|
p1 = pop()
|
|
|
|
if (p1 == symbol(E))
|
|
push_integer(1)
|
|
return
|
|
|
|
if (equaln(p1, 1))
|
|
push_integer(0)
|
|
return
|
|
|
|
if (isnegativenumber(p1))
|
|
push(p1)
|
|
negate()
|
|
logarithm()
|
|
push(imaginaryunit)
|
|
if evaluatingAsFloats
|
|
push_double(Math.PI)
|
|
else
|
|
push_symbol(PI)
|
|
multiply()
|
|
add()
|
|
return
|
|
|
|
if (isdouble(p1))
|
|
d = Math.log(p1.d)
|
|
push_double(d)
|
|
return
|
|
|
|
# rational number and not an integer?
|
|
|
|
if (isfraction(p1))
|
|
push(p1)
|
|
numerator()
|
|
logarithm()
|
|
push(p1)
|
|
denominator()
|
|
logarithm()
|
|
subtract()
|
|
return
|
|
|
|
# log(a ^ b) --> b log(a)
|
|
|
|
if (car(p1) == symbol(POWER))
|
|
push(caddr(p1))
|
|
push(cadr(p1))
|
|
logarithm()
|
|
multiply()
|
|
return
|
|
|
|
# log(a * b) --> log(a) + log(b)
|
|
|
|
if (car(p1) == symbol(MULTIPLY))
|
|
push_integer(0)
|
|
p1 = cdr(p1)
|
|
while (iscons(p1))
|
|
push(car(p1))
|
|
logarithm()
|
|
add()
|
|
p1 = cdr(p1)
|
|
return
|
|
|
|
push_symbol(LOG)
|
|
push(p1)
|
|
list(2)
|
|
|