Someone else submitted a BigMath::log speedup at
http://www.rcrchive.net/rcr/show/322. This doesn't appear to be a big
enough change for an RCR, so I'm submitting it as a patch. To save
you a bit of time, I've combined the suggested log method with the
original (they were separate methods in the RCR) and removed the need
for bigdecimal/util.rb :
In bigdecimal/math.rb :
def log(x, prec)
raise ArgumentError, "Zero or negative argument for log" if x <= 0
|| prec <= 0
return x if x.infinite? || x.nan?
if x > 10
sign, fraction, power, exponent = x.split
fraction = BigDecimal(".#{fraction}")
power = BigDecimal(power.to_s)
log(fraction, prec) + (log(power, prec) * exponent)
else
one = BigDecimal("1")
two = BigDecimal("2")
n = prec + BigDecimal.double_fig
x = (x - one).div(x + one,n)
x2 = x.mult(x,n)
y = x
d = y
i = one
while d.nonzero? && ((m = n - (y.exponent - d.exponent).abs) > 0)
m = BigDecimal.double_fig if m < BigDecimal.double_fig
x = x2.mult(x,n)
i += two
d = x.div(i,m)
y += d
end
y * two
end
end
I've only tested this by taking the logarithm of 500 to a precision of
200. This sped it up quite a bit. If this is good, can someone
please patch it in and attribute it to leonardr on the RCR site
(rather than me) ? Thanks.