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]

Reply via email to