The following code demonstrates another way of calculating natural logarithms and gives you some idea of the speed on your machine.
sync on: sync rate 0: sync
` make memblock 99, 4 ` see comment in function
x# = 3456789.0 ` just any old number
start = timer()
nmax = 1000000
for n = 1 to nmax
lx# = ln(x#)
next n
start = timer() - start
repeat
text 20, 20, str$(nmax)+" function calls"
text 20, 40, " took "+str$(start)+" msecs, x= "+str$(x#, 8)+" LN(x)="+str$(lx#, 8)
sync
until spacekey()
end
function LN(x as float)
` Green Gandalf's natural log function
` accurate to about 6 decimal places
` (unless x is VERY large or small)
` written 20 May 2007, amended 21 May 2007
` NOTE - no checks for valid x values yet!!
` create memblock for float to dword conversion,
` replace 99 by another convenient memblock number if necessary,
` runs slightly faster if memblock is created in main program
` and following line removed
if memblock exist(99) = 0 then make memblock 99, 4
` split x into exponent and mantissa
d as dword
mant as dword
expon as integer
write memblock float 99, 0, x
d = memblock dword(99, 0)
` magic bit constants based on information provided by IanM
mant= (%00000000011111111111111111111111&&d)||%00111111100000000000000000000000
expon=((%01111111100000000000000000000000&&d)>>23) - 127
write memblock dword 99, 0, mant
` x should be in the range 1.0 to 2.0
x = memblock float( 99, 0)
` adjust range to 1/sqrt(2) to sqrt(2) for accuracy
if x > 1.414213562
inc expon
x = x / 2.0
endif
` calculate series approximation to LN(x)
arg# = (x - 1.0)/(x + 1.0)
arg2# = arg# * arg#
sum# = 1.0
fac# = 2.0 * arg#
arg# = arg2#
div# = 3.0
for i = 1 to 2 ` upper limit of 3 is slightly slower and more accurate
inc sum#, arg2#/div#
inc div#, 2.0
arg2# = arg2# * arg#
next i
result# = sum# * fac# + expon * 0.69314718
endfunction result#
Let me know if you experience problems with certain number ranges. It should run at much the same speed regardless of the value whose logarithm is required.