roboticus,
Removing a node's content is generally frowned upon regardless of correctness. It is best to strike what is wrong or add an update then to remove it entirely. People do learn from other's mistakes.
FWIW, here is my take without having looked any other solutions to include monsieur_champs'.
print sqrt($_), "\t", mysqrt($_, .0000001), "\n" for qw/.25 .50 .75 1
+10 50 100 1000 31415926/;
sub mysqrt {
my ($tgt, $err, $try, $len) = @_;
return 1 if $tgt == 1;
if (! defined $try) {
($len, $try) = $tgt < 1
? ((1 - $tgt) / 2, $tgt + (1 - $tgt) / 2)
: ($tgt / 2, $tgt / 2);
return mysqrt($tgt, $err, $try, $len);
}
my $dif = $tgt - ($try * $try);
return $try if abs($dif) < $err;
$len /= 2;
$try = $dif > 0 ? $try + $len : $try - $len;
return mysqrt($tgt, $err, $try, $len);
}
If it isn't obvious, it is a binary search.
Update: The adjustment for values < 1 can be mathematically simplified. Additionally, a much faster converging algorithm would be $try = (($tgt / $try) + $try) / 2.
|