CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
Cube root and negatives

 



alwayslooking20
New User

Jun 1, 2011, 6:03 AM

Post #1 of 7 (1335 views)
Cube root and negatives Can't Post

I am writing a program ("perl.pl") that reads a file ("file.txt"). "perl.pl"

Code
#!/usr/bin/perl 

$NEWFILE="file.txt";
open (NEWFILE);
@fileinput = <NEWFILE>;

foreach my $i (0..8) {
$cube=($fileinput[$i] ** (1/3));
print "$cube\n";
}


"file.txt"

Code
1 
8
27
64
-64
-27
-8
-1
0


Yet, it returns this:

Code
1 
2
3
4
-nan
-nan
-nan
-nan
0


How do I get this to return the proper values?


rovf
Veteran

Jun 1, 2011, 7:45 AM

Post #2 of 7 (1330 views)
Re: [alwayslooking20] Cube root and negatives [In reply to] Can't Post

I guess that Perl, when calculating the exponent of a non-integral number, uses the logarithm to get at the result.

I suggest that you handle the sign manually.


BillKSmith
Veteran

Jun 1, 2011, 7:50 AM

Post #3 of 7 (1329 views)
Re: [alwayslooking20] Cube root and negatives [In reply to] Can't Post

In general, raising a negative number to a non-integer power gives a complex number. Perl is reporting this even for the special case in which you know that the imagainary component is zero.

I would write a cube_root function which takes the cube root of the absolute value and then sets the sign to be the same as the original number.
Good Luck,
Bill


alwayslooking20
New User

Jun 1, 2011, 7:57 AM

Post #4 of 7 (1327 views)
Re: [BillKSmith] Cube root and negatives [In reply to] Can't Post

How would I go about doing that? Example?


BillKSmith
Veteran

Jun 1, 2011, 8:26 AM

Post #5 of 7 (1323 views)
Re: [alwayslooking20] Cube root and negatives [In reply to] Can't Post


Code
use strict; 
use warnings;
while ( my $cube = <DATA>) {
my $cube_root= cube_root( $cube );
print "$cube_root\n";
}

sub cube_root {
( my $cube ) = @_;
die "No argument defined for cube root\n" if !defined $cube;
return 0 if $cube == 0;
my $cube_root = ( abs($cube) )**( 1 / 3 );
my $sign = $cube / abs($cube);
return $sign * $cube_root;
}
__END__
1
8
27
64
-64
-27
-8
-1
0



For production code, you should also use a module to verify that the argument of the function is numeric.
Good Luck,
Bill


alwayslooking20
New User

Jun 1, 2011, 9:18 AM

Post #6 of 7 (1317 views)
Re: [BillKSmith] Cube root and negatives [In reply to] Can't Post

thanks, I did this:


Code
#!/usr/bin/perl                                                

$NEWFILE="file.txt";
open (NEWFILE);
@fileinput = <NEWFILE>;

foreach my $i (0..9) {

if ($fileinput[$i] == 0){
print "0\n";
}
else
{
$sign = ($fileinput[$i] / abs($fileinput[$i]));
$cube_no_sign= (abs($fileinput[$i]) **(1/3));
$cube=($cube_no_sign * $sign);
print $cube;
print "\n";
}
}



BillKSmith
Veteran

Jun 1, 2011, 8:42 PM

Post #7 of 7 (1298 views)
Re: [alwayslooking20] Cube root and negatives [In reply to] Can't Post

Your solution does work, but there are several reasons to prefer the subroutine solution.

Probably the most important is that it is self documenting. It makes it very clear to any reader that you intend to take a cube root.

When you get around to my final suggestion, you will discover that we both forgot about the newline on the number. We both got away with it for now, but it is poor practice to do arithmetic with anything but pure numbers.

In the future, you may find a faster or more accurate algorithm. Change the function and you have made the change everywhere that it is used.

A function can, and should, be tested independent of the rest of the program. Do you have any idea what your program would (or even should) do if there is a blank line in the file. The function should throw an exception (die) when it finds any non-numeric argument.

You may find a well tested cube-root function on CPAN. It is a trivial change to replace the call to one function with a call to a better one.
Good Luck,
Bill

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives