Re: root function
by FunkyMonk (Chancellor) on Jun 21, 2008 at 18:33 UTC
|
It's just basic maths. The cube root of 27 is 27**(1/3). If you really want a function, try
print wop( 8, 3 ); #2
print wop( 27, 3 ); #3
sub wop {
my ( $base, $root ) = @_;
return $base ** (1/$root)
}
update: s/If/If you/
| [reply] [d/l] |
|
You're going to have to rename that function "whop" for a US audience. :)
| [reply] |
Re: root function
by swampyankee (Parson) on Jun 21, 2008 at 21:18 UTC
|
FunkyMonk has one way; another is
x(1/y) = eln(x)/y. Just beware that 00 should be undefined, and Perl's ** operator is essentially a wrapper around C's "pow" function, so it will almost certainly puke on (-3)(1/3), even though it shouldn't.
Information about American English usage here and here. Floating point issues? Please read this before posting. — emc
| [reply] |
|
Yes it does. (-3)**(1/3) results in nan; But so does the log approach, too.
The odd roots of negative numbers must be treated separately as they are limit cases.
I'd try something like:
if ($base>0) {
return $base**(1/$root);
} elsif ($base==0) {
return 0; ## or do manage the special case 0**0;
} elsif ($root)==int($root) && $root%2==1) {
return -((-$base)**($root));
} else {
return 'nan';
}
Not tested, so probably broken :)
Careful with that hash Eugene.
| [reply] [d/l] |
|
The logarithms of negative numbers are defined; it's just that they require complex numbers to represent. It's not my fault that Perl (and C) can't cope with them ;-).
All will become clear when one remembers that eπi = -1
Information about American English usage here and here. Floating point issues? Please read this before posting. — emc
| [reply] |
|
|
|
|
|
$ perl -le'print -3 ** (1/3)'
-1.44224957030741
ActivePerl:
>perl -le"print -3 ** (1/3)"
-1.44224957030741
Update: Oops, precedence problem
$ perl -le'print( (-3) ** (1/3) )'
nan
>perl -e"print( (-3) ** (1/3) )"
-1.#IND
| [reply] [d/l] [select] |
|
sini@ordinalfabetix:~$ perl -le"print ((-3)**(1/3));"
nan
sini@ordinalfabetix:~$
Exponent operator ** has higher priority than unary minus so you are doing -(3**(1/3)) instead of ((-3)**(1/3)).
This gives you accidentally the right result but it would tell you that square root of -2 == -1.414265...
Careful with that hash Eugene.
| [reply] [d/l] |
|
|
|
Re: root function
by Sixtease (Friar) on Jun 21, 2008 at 18:37 UTC
|
I have also found the Math::NumberCruncher module, which seems to have a function for that.
use strict; use warnings; print "Just Another Perl Hacker\n";
| [reply] |
|
| [reply] |
Re: root function
by casiano (Pilgrim) on Jun 22, 2008 at 10:35 UTC
|
Perl with the help of
PDL::Complex
can cope with Complex Numbers. See below:
pp2@nereida:~/.ssh$ perl -wde 0
main::(-e:1): 0
DB<1> use PDL
DB<2> use PDL::Complex
DB<3> $x = r2C(-27) # From real to complex
DB<4> $r = Croots $x, 3 # There are three complex roots
DB<5> print $r # It is sad that there is a bug
# with "" overload
Use of uninitialized value in numeric ...
[
1.5 +2.59807621135332i
-3 +3.67381906146713e-16i
1.5 -2.59807621135332i
]
DB<6> x $ra # The answer is a PDL object
0 PDL::Complex=SCALAR(0x8a6a0a8)
-> 144899352
DB<7> p re $r # Get the "real" components
[1.5 -3 1.5]
DB<8> p im $r # And the imaginary ones:
[ 2.5980762 3.6738191e-16 -2.5980762]
DB<9> $y = $r ** 3 # Check the solution:
DB<10> p re $y
[-27 -27 -27]
DB<11> p im $y # Almost 0, as expected
[3.3064372e-15 9.9193115e-15 6.8636015e-14]
Hope it helps
Casiano | [reply] [d/l] |
|
| [reply] [d/l] |
Re: root function
by igelkott (Priest) on Jun 22, 2008 at 00:55 UTC
|
calculate the root
Besides the suggested home-made functions, you could also try pow in the POSIX module.
| [reply] |
|
Either you're calling ** a home-made function, or they're just as needed for pow as for **.
| [reply] [d/l] [select] |
|
| [reply] [d/l] |
|