[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Implementation of log(x) for SPARC32
- To: <linux-il(at-nospam)linux.org.il>
- Subject: Re: Implementation of log(x) for SPARC32
- From: Shlomi Fish <shlomif(at-nospam)techst02.technion.ac.il>
- Date: Tue, 25 Dec 2001 17:54:49 +0200 (IST)
- Cc: "Nadav Har'El" <nyh(at-nospam)math.technion.ac.il>
- Delivered-To: linux.org.il-linux-il@linux.org.il
- In-Reply-To: <m3n107fkmp.fsf@hedwig.data-zoo.com>
- Sender: linux-il-bounce(at-nospam)cs.huji.ac.il
On 25 Dec 2001, Oleg Goldshmidt wrote:
> Shlomi Fish <shlomif@techst02.technion.ac.il> writes:
>
> > But who is John Galt? Speed is not of the outmost importance in this case,
> > so I think my implementation is fine.
>
> Only you can judge that. It's not only speed - are you sure that
> whatever approximation you used (I have not looked at your perl code)
> will not blow up - ever?
>
Actually, I checked it against the numbers in the range 0 .. 1, which is
my working range, and I discovered it returns very inaccurate results.
With some input from Ehud Karni, I wrote an improved function that uses a
different taylor series. Here it is for your reference:
######################
#!/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 $sign_rev = 0;
if ($number <= 0)
{
# Return -google. Close to -inf.
return -10e100;
}
my $exp_base = 0;
if ($number < 1)
{
while ($number < 0.5)
{
$number *= $e_const;
$exp_base--;
}
}
else
{
while ($number > 2)
{
$number *= $e_const_reci;
$exp_base++;
}
}
if ($number == 1)
{
return 0+$exp_base;
}
elsif ($number < 1)
{
$number = 1/$number;
$sign_rev = 1;
}
my $expr = (($number-1)/($number+1));
my $expr_squared = $expr*$expr;
my $x_to_the_power_of_n = 2*$expr;
my $result = 0;
for(my $a = 1; $a < 29 ; $a++, $a++)
{
$result += $x_to_the_power_of_n/$a;
$x_to_the_power_of_n *= $expr_squared;
}
if ($sign_rev)
{
$result = -$result;
}
$result += $exp_base;
return $result;
}
##########################
This seems to work fine on all input. Thanks for making me aware of it.
Regards,
Shlomi Fish
> > If anybody can point me to a highly optimized code in C, that I can
> > easily rip and compile as part of the kernel, I would use that
> > instead.
>
> Search for IEEE 754? At least look up Abramowitz and Stegun and
> compare what you do to what they write, check applicability.
>
> --
> Oleg Goldshmidt | ogoldshmidt@NOSPAM.computer.org
> "If it ain't broken, it has not got enough features yet."
>
> =================================================================
> To unsubscribe, send mail to linux-il-request@linux.org.il with
> the word "unsubscribe" in the message body, e.g., run the command
> echo unsubscribe | mail linux-il-request@linux.org.il
>
----------------------------------------------------------------------
Shlomi Fish shlomif@t2.technion.ac.il
Home Page: http://t2.technion.ac.il/~shlomif/
Home E-mail: shlomif@techie.com
"Let's suppose you have a table with 2^n cups..."
"Wait a second - is n a natural number?"
=================================================================
To unsubscribe, send mail to linux-il-request@linux.org.il with
the word "unsubscribe" in the message body, e.g., run the command
echo unsubscribe | mail linux-il-request@linux.org.il