On Tue, 25 Dec 2001 13:23:20 +0200 (IST), Shlomi Fish <[EMAIL PROTECTED]> wrote: > > FYI, I eventually gave up and coded a logarithm function in perl: > > ################# > #!/usr/bin/perl > > use strict; > > my $e_const = exp(1); > my $e_const_reci = (1/$e_const); > > my $number = shift || 516; > > printf("%.80lf\n", mylog($number)); > printf("%.80lf\n", log($number)); > > sub mylog > { > my $number = shift; > my $exp_base = 0; > while ($number > 2) > { > $number *= $e_const_reci; > $exp_base++; > } > $number -= 1; > my $x_times_n = $number; > my $result = 0; > for(my $a = 1; $a < 28 ; $a++) > { > if ($a & 0x1) > { > $result += $x_times_n/$a; > } > else > { > $result -= $x_times_n/$a; > } > $x_times_n *= $number; > #printf("%i: %.80lf\n", $a, $result); > } > return $result+$exp_base; > } > ##################################### > > Works like a charm with exactly the same accuracy. I'm going to convert it > to C, and by this I will have a truly portable log() implementation for > the kernel. > > IMO, someone should port stuff like a large part of glibc as well as STL, > etc to the kernel. That would make the lives of programmers much easier > because they won't have to reinvent the wheel times and again.
May I suggest a small improvement ? You are using the Taylor series for ln(1+X). It is better to use the series for ln((1+X)/(1-X)) which is 2*(X+X**3/3+X**5/5+..X**(2n-1)/(2n-1)...) There is no sign change and it needs half the numbers of terms. If you have T [between 0.5 and 2] and you do T=(1+X)/(1-X), you'll get X=(T-1)/(T+1) which gives you an |X| < 0.334. This will converge very quickly (for 14 decimal digits precision you need only 15 iterations) Ehud. -- Ehud Karni Tel: +972-3-7966-561 /"\ Mivtach - Simon Fax: +972-3-7966-667 \ / ASCII Ribbon Campaign Insurance agencies (USA) voice mail and X Against HTML Mail http://www.mvs.co.il FAX: 1-815-5509341 / \ mailto:[EMAIL PROTECTED] Better Safe Than Sorry ================================================================= To unsubscribe, send mail to [EMAIL PROTECTED] with the word "unsubscribe" in the message body, e.g., run the command echo unsubscribe | mail [EMAIL PROTECTED]