以前使用したルーチン(「適切な」ものかどうかはわかりません)は、分割統治法です。
まず、任意の上限値と下限値(たとえば、それぞれ5と0-検索する最大および最小の平方根)から始め、それらの間の中間点を見つけます。その値を二乗します。
二乗値がターゲットより大きい場合は、上限値を二乗値に設定します。低い場合は、低い値を設定してください。
二乗値がルックアップ値と一致するか、必要なだけ正確になるのに十分な反復を実行するまで繰り返します。
これは私がperlで一緒にノックした小さなバージョンです:
#!/usr/bin/perl
my $val = shift;
my $max = 5;
my $min = 0;
my $iterations = 0;
my $maxiter = 40;
while(($max > $min) and ($iterations<$maxiter))
{
$iterations++;
my $diff = $min + ($max - $min) / 2;
my $square = $diff * $diff;
if($square == $val)
{
print "Square root found at $diff\n";
print "$iterations iterations\n";
exit(0);
} else {
if($square > $val)
{
$max = $diff;
} else {
$min = $diff;
}
}
}
my $diff = $min + ($max - $min) / 2;
print "Approximate square root after $iterations iterations: $diff\n";
もちろん、これは浮動小数点を使用していますが、固定小数点に簡単に適合させることができます。反復制限を変更することにより、精度を変えることができます。各反復は、以前の反復よりもわずかに正確になります。
例:-9の平方根を求めます。
Approximate square root after 40 iterations: 2.99999999999955
- or -
Approximate square root after 10 iterations: 3.00048828125
- or -
Approximate square root after 5 iterations: 3.046875
値3が見つかった場合は、当然、早い段階で停止していました。
十分な反復を与えると、非常に正確になります。
./sqrt.pl 0.00284
Square root found at 0.0532916503778969
59 iterations