Hey, cool problem, nysus... I'll throw out my code, first. Be forewarned, though -- I'm nowhere near the pro you asked for.
#!/usr/bin/perl -w
use strict;
sub sqroot {
my $maxdiff = 1e-18;
my ($value, $num) = (1, shift @_);
my $i = ''; # Added
$num *= -1 and $i = 'i' if ($num < 0); # Added
my $oldvalue = 0;
while (abs($oldvalue - $value) > $maxdiff) {
$oldvalue = $value;
$value = $num / $value;
$value = ($value + $oldvalue) / 2;
}
# return $value; # (old)
return $value . $i;
}
my $num;
do {
print "Please enter a number: "; # changed from "positive number"
chomp ($num = <STDIN>);
# } until ($num =~ /^\d*[.\d]\d*$/); # (old regex)
} until ($num =~ /^-?\d+\.?\d*$/);
my $sqrt = sqroot $num;
print "Square root of $num: $sqrt\n";
Now, for a few comments:
- IMO, your code was broken down perhaps a little too much. Of course, depending on what you'll want to do in the future, you may want to do that. But I'd suggest a name such as diff instead of get_accuracy, for two reasons: it is shorter (which I know can be a bad thing in some cases), and it's more descriptive of its function. You're only returning the difference between the two numbers, and I'd prefer something that I'd be able to easily recognize later on, so I could steal it and put it in another program.
- Also, I moved the print statement out of the subs... once again, it's only my opinion, but I think those things should be outside of the sub (If I call "sqroot", I don't expect it to print anything out. "print_sqrt" on the other hand...)
- You'll notice I also have a different regex and a do-until loop... the loop style is just personal preference, but I feel the regex is better, as it allows the user to enter in just the number (e.g. "10" vs. "10.0"), however, it may not be the most efficent. I'd like a little feedback from those who know more than I on that, actually...
Once again, considering that optimial is a relative term, you're free to call my ideas ridiculous, if you like. :) Once again, though, cool problem... made me think a good bit. (I'll probably still be thinking about it tomorrow...)
Update: I just couldn't leave well enough alone. Above are modifications to the original script that allow processing of negative numbers, as well as an improved (?) regex. Also changed $maxdiff as per ariels' suggestion.
His Royal Cheeziness