Perl-Sensitive Sunglasses PerlMonks

### Re: [OT] Function to do x**y for |y|<1 w/o ** operator.

by salva (Abbot)
 on Feb 20, 2013 at 11:37 UTC ( #1019768=note: print w/replies, xml ) Need Help??

Another solution based on the fact that a floating point number is actually a sum of powers of 2.

For 0 <= y <= 0, it holds that y = b0*20 + b1*2-1 + b2*2-2 + b3*2-3 + ...

And so, xy = xb0*20 + b1*2-1 + b2*2-2 + b3*2-3 + ... = xb0*20 * xb1*2-1 * xb2*2-2 * xb3*2-3 * ... = Πi, bi≠0 x2-i

Which in Perl becomes...

```#!/usr/bin/perl

use strict;
use warnings;

my (\$X, \$Y, \$n) = @ARGV;
\$n ||= 20;

my \$Z = \$X ** \$Y;

my (\$neg, \$y) = (\$Y < 0 ? (1, -\$Y) : (0, \$Y));

\$y > 1 and die "Y is out of range";
my \$bit = 1;
my \$x = \$X;
my \$z = 1;
while (\$y) {
if (\$y >= \$bit) {
\$y -= \$bit;
\$z *= \$x;
}
\$bit /= 2;
\$x = sqrt(\$x);
}

\$z = 1/\$z if \$neg;
my \$e = abs(\$z - \$X ** \$Y);
print "z=\$z, e=\$e\n";

sqrt is also an expensive operation. If you have to calculate xy for different values of y while x stays constant, you may be able to speed up the process creating a table with the values of x2-i.

Alternatively, you can write a function to calculate ex (using a table with the values of e2i), and then calculate xy as elog(x)*y.

update: there are also several implementations of exp(x) freely available, for instance, the one in OpenBSD is here.

Create A New User
Node Status?
node history
Node Type: note [id://1019768]
help
Chatterbox?
 [1nickt]: That's cool Disci+

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2018-01-24 03:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
How did you see in the new year?

Results (255 votes). Check out past polls.

Notices?