平方根を計算するアルゴリズム
平方根を計算する方法は、正の 実数 の 非負の 平方根を近似する アルゴリズム です。 完全平方 以外の 自然数 の平方根はすべて 無理数 であるため 、
平方根は通常、有限の精度でしか計算できません。これらの方法では通常、精度が徐々に高くなる一連の 近似値 を構築します。
S
{\displaystyle {\sqrt {S}}}
S
{\displaystyle S}
ほとんどの平方根の計算方法は反復的です。 の適切な初期推定値を選択した後、何らかの終了基準が満たされるまで反復的な改良が実行されます。 改良スキームの 1 つに、 ニュートン法 の特殊なケースであるヘロン法があります 。 除算が乗算よりもはるかにコストがかかる場合は、代わりに逆平方根を計算する方が望ましい場合があります。
S
{\displaystyle {\sqrt {S}}}
平方根を桁ごとに計算する方法や、テイラー級数を使用する方法もあります。平方根の有理近似値は、連分数展開を使用して計算できます。
採用される方法は、必要な精度、利用可能なツール、計算能力によって異なります。方法は、暗算に適したもの、通常は少なくとも紙と鉛筆を必要とするもの、デジタル電子コンピュータまたはその他の計算デバイスで実行されるプログラムとして実装されるものに大まかに分類できます。アルゴリズムでは、収束 (指定された精度を達成するために必要な反復回数)、個々の操作 (除算など) または反復の計算の複雑さ、およびエラーの伝播 (最終結果の精度) が考慮される場合があります。
紙と鉛筆による合成除算や級数展開などのいくつかの方法では、開始値は必要ありません。一部のアプリケーションでは、最も近い整数に丸められた、または切り捨てられた平方根である 整数平方根 が必要です (この場合は、修正された手順が使用される場合があります)。
歴史
平方根(特に 2 の平方根 )を求める手順は、少なくとも紀元前 17 世紀の古代バビロニアの時代から知られていました。
バビロニアの数学者は 2 の平方根を 1 の後の 60 進法の 3 桁で計算しましたが、その正確な方法はわかっていません。彼らは斜辺を
(たとえば、高さが ロッド、幅がロッド の門の対角線)を使って近似する方法を知っており、同様のアプローチを使用して の近似値を求めていた可能性があります。
1つの
2
+
b
2
≈
1つの
+
1
2
b
2
1つの
−
1
{\displaystyle {\sqrt {a^{2}+b^{2}}}\approx a+{\frac {1}{2}}b^{2}a^{-1}}
41
60
+
15
3600
{\displaystyle {\frac {41}{60}}+{\frac {15}{3600}}}
40
60
{\displaystyle {\frac {40}{60}}}
10
60
{\displaystyle {\frac {10}{60}}}
2
。
{\displaystyle {\sqrt {2}}.}
1世紀エジプトのヘロン法は 、平方根を計算するための最初の確認可能なアルゴリズムでした。
現代の分析手法は、ルネサンス初期に西ヨーロッパに アラビア数字 が導入されてから開発され始めました。 [ 要出典 ]
現在、ほぼすべてのコンピューティング デバイスには、プログラミング言語構造、コンパイラの組み込み関数またはライブラリ関数、または説明した手順のいずれかに基づくハードウェア演算子として、高速で正確な平方根関数が備わっています。
初期見積もり
多くの反復平方根アルゴリズムでは、初期 シード値 が必要です。シードは 0 以外の正の数で、 平方根を求める必要がある数である 1 から までの範囲でなければなりません。これは、平方根がその範囲内になければならないためです。シードが平方根から大きく離れている場合、アルゴリズムはより多くの反復を必要とします。 (または ) で初期化すると、 平方根の大きさの桁を取得するだけで、おおよそ 回の反復が無駄になります。したがって、精度は限られるかもしれませんが計算しやすい大まかな推定値があると便利です。一般に、初期推定値が優れているほど、収束は速くなります。ニュートン法 (バビロニア法またはヘロン法とも呼ばれる) では、平方根よりいくらか大きいシードは、平方根よりいくらか小さいシードよりもわずかに速く収束します。
S
{\displaystyle S}
x
0
=
1
{\displaystyle x_{0}=1}
S
{\displaystyle S}
1
2
|
ログ
2
S
|
{\displaystyle {\tfrac {1}{2}}\vert \log _{2}S\vert }
一般に、推定は根を含むことが分かっている任意の区間( など )に従います。推定は、 区間における への関数近似の特定の値です。より良い推定を得るには、区間のより厳しい境界を得るか、 へのより良い関数近似を見つける必要があります 。後者は通常、近似に高次の多項式を使用することを意味しますが、すべての近似が多項式であるとは限りません。一般的な推定方法には、スカラー、線形、双曲、対数などがあります。暗算または紙と鉛筆による推定には、通常、10 進法が使用されます。コンピュータによる推定には、2 進法がより適しています。推定では、数値が科学的記数法で表されるため、指数と 仮数は 通常別々に扱われます。
[
x
0
、
S
/
x
0
]
{\displaystyle [x_{0},S/x_{0}]}
f
(
x
)
=
x
{\displaystyle f(x)={\sqrt {x}}}
f
(
x
)
{\displaystyle f(x)}
小数点推定値
通常、この数値は 科学的記数法 でと 表されます。 ここで 、 n は 整数であり、平方根の可能な範囲は です 。
S
{\displaystyle S}
a
×
10
2
n
{\displaystyle a\times 10^{2n}}
1
≤
a
<
100
{\displaystyle 1\leq a<100}
a
×
10
n
{\displaystyle {\sqrt {a}}\times 10^{n}}
1
≤
a
<
10
{\displaystyle 1\leq {\sqrt {a}}<10}
スカラー推定
スカラー法では、範囲を区間に分割し、各区間の推定値は単一のスカラー数で表されます。範囲を単一の区間とみなす場合、算術平均 (5.5) または幾何平均 ( ) の時間 が妥当な推定値となります。これらの絶対誤差と相対誤差は異なります。一般に、単一のスカラーは非常に不正確です。範囲を 2 つ以上の区間に分割すると推定値が向上しますが、スカラー推定値は本質的に精度が低くなります。
10
≈
3.16
{\displaystyle {\sqrt {10}}\approx 3.16}
10
n
{\displaystyle 10^{n}}
2つの区間を幾何的に分割した場合、平方根は 次のように推定できる [注1]。
S
=
a
×
10
n
{\displaystyle {\sqrt {S}}={\sqrt {a}}\times 10^{n}}
S
≈
{
2
⋅
10
n
if
a
<
10
,
6
⋅
10
n
if
a
≥
10.
{\displaystyle {\sqrt {S}}\approx {\begin{cases}2\cdot 10^{n}&{\text{if }}a<10,\\6\cdot 10^{n}&{\text{if }}a\geq 10.\end{cases}}}
この推定値は、a = 100 で最大絶対誤差となり 、a = 1 で最大相対誤差が 100% となります。
4
⋅
10
n
{\displaystyle 4\cdot 10^{n}}
たとえば、 を として因数分解すると 、推定値は となり 、 絶対誤差は 246、相対誤差はほぼ 70% になります。
S
=
125348
{\displaystyle S=125348}
12.5348
×
10
4
{\displaystyle 12.5348\times 10^{4}}
S
≈
6
⋅
10
2
=
600
{\displaystyle {\sqrt {S}}\approx 6\cdot 10^{2}=600}
125348
=
354.0
{\displaystyle {\sqrt {125348}}=354.0}
線形推定
よりよい推定値、そして使用される標準的な方法は、小さな円弧上の 関数の線形近似です。上記のように、底の累乗が数から因数分解され 、区間が に縮小された場合 、円弧にまたがる割線、または円弧に沿ったどこかの接線が近似値として使用されますが、円弧と交差する最小二乗回帰線の方がより正確です。
y
=
x
2
{\displaystyle y=x^{2}}
S
{\displaystyle S}
[
1
,
100
]
{\displaystyle [1,100]}
最小二乗回帰直線は、推定値と関数の値の平均差を最小化します。その方程式は です 。並べ替え、 計算を容易にするために係数を丸めます。
y
=
8.7
x
−
10
{\displaystyle y=8.7x-10}
x
=
0.115
y
+
1.15
{\displaystyle x=0.115y+1.15}
S
≈
(
a
/
10
+
1.2
)
⋅
10
n
{\displaystyle {\sqrt {S}}\approx (a/10+1.2)\cdot 10^{n}}
これは、区間 における関数 y=x 2 の単一部分線形近似によって達成できる 平均的に 最良の推定値です 。a=100 で最大絶対誤差は 1.2、S=1 および 10 で最大相対誤差は 30% です。 [注 2]
[
1
,
100
]
{\displaystyle [1,100]}
10 で割るには、 の指数から 1 を引く か、比喩的に小数点を 1 桁左に移動します。この定式化では、任意の加法定数 1 に小さな増分を加えたものが適切な推定値となるため、正確な数値を覚えておくことは負担にはなりません。範囲を 1 本の線で結んだ近似値 (四捨五入の有無にかかわらず) は、精度の有効桁数が 1 未満です。相対誤差は 1/2 2 より大きいため 、提供される情報は 2 ビット未満です。範囲が 2 桁と、この種の推定値としては非常に大きいため、精度は大幅に制限されます。
a
{\displaystyle a}
[
1
,
100
]
{\displaystyle [1,100]}
区分線形近似、つまり複数の線分でそれぞれ元の円弧の一部を近似すると、より正確な推定値が得られます。使用する線分が多いほど、近似値は高くなります。最も一般的な方法は接線を使用することです。重要な選択は、円弧をどのように分割するか、どこに接点を配置するかです。円弧を y = 1から y = 100 まで分割する効果的な方法は、幾何学的に分割することです。2 つの区間の場合、区間の境界は元の区間の境界の平方根 1×100、つまり [1, 2 √ 100 ] と [ 2 √ 100 ,100] になります。 3 つの区間の場合、境界は 100 の 3 乗根です: [1, 3 √ 100 ]、[ 3 √ 100 ,( 3 √ 100 ) 2 ]、[( 3 √ 100 ) 2 ,100] など。2 つの区間の場合、 2 √ 100 = 10 となり、非常に便利な数となります。接線は簡単に導出でき、x = √ 1* √ 10 および x = √ 10* √ 10 にあります。それらの式は、 およびです 。これを反転すると、平方根は、 およびです 。したがって、 の場合 :
y
=
3.56
x
−
3.16
{\displaystyle y=3.56x-3.16}
y
=
11.2
x
−
31.6
{\displaystyle y=11.2x-31.6}
x
=
0.28
y
+
0.89
{\displaystyle x=0.28y+0.89}
x
=
.089
y
+
2.8
{\displaystyle x=.089y+2.8}
S
=
a
⋅
10
2
n
{\displaystyle S=a\cdot 10^{2n}}
S
≈
{
(
0.28
a
+
0.89
)
⋅
10
n
if
a
<
10
,
(
.089
a
+
2.8
)
⋅
10
n
if
a
≥
10.
{\displaystyle {\sqrt {S}}\approx {\begin{cases}(0.28a+0.89)\cdot 10^{n}&{\text{if }}a<10,\\(.089a+2.8)\cdot 10^{n}&{\text{if }}a\geq 10.\end{cases}}}
絶対誤差の最大値は、区間の最高点である a =10 と 100 で発生し、それぞれ 0.54 と 1.7 です。相対誤差の最大値は、区間の終点である a =1、10、100 で発生し、どちらの場合も 17% です。17% または 0.17 は 1/10 より大きいため、この方法では小数点以下の精度しか得られません。
双曲線推定
場合によっては、双曲線推定が有効なことがあります。双曲線も凸曲線であり、 直線よりもY = x 2 の弧に沿っている可能性が高いためです。双曲線推定は、浮動小数点除算を必要とするため、計算がより複雑になります。区間上のx 2 のほぼ最適な双曲線近似は、y=190/(10-x)-20 です。転置すると、平方根は x = -190/(y+20)+10 です。したがって 、
[
1
,
100
]
{\displaystyle [1,100]}
S
=
a
⋅
10
2
n
{\displaystyle S=a\cdot 10^{2n}}
S
≈
(
−
190
a
+
20
+
10
)
⋅
10
n
{\displaystyle {\sqrt {S}}\approx \left({\frac {-190}{a+20}}+10\right)\cdot 10^{n}}
浮動小数点除算は、小数点 1 桁まで正確であれば十分です。これは、全体的な推定値がその精度で、頭の中で実行できるためです。双曲推定値は、平均するとスカラー推定値や線形推定値よりも優れています。最大絶対誤差は 100 で 1.58、最大相対誤差は 10 で 16.0% です。a=10 での最悪のケースでは、推定値は 3.67 です。10 から始めてすぐにニュートン ラプソン反復法を適用すると、双曲推定値の精度を超えるまでに 2 回の反復が必要になり、3.66 になります。75 のようなより一般的なケースでは、双曲推定値は 8.00 で、より正確な結果を得るには 75 から 5 回のニュートン ラプソン反復法が必要になります。
算術推定
区分線形近似に似ていますが、代数方程式の代わりに算術のみを使用する方法では、掛け算表を逆に使用します。1 から 100 までの数の平方根は 1 から 10 の間です。したがって、25 が完全な平方数 (5 × 5) で、36 が完全な平方数 (6 × 6) であることがわかっている場合、25 以上 36 未満の数の平方根は 5 で始まります。他の平方数の間の数についても同様です。この方法では最初の桁は正しくなりますが、1 桁正確ではありません。たとえば、35 の平方根の最初の桁は 5 ですが、35 の平方根はほぼ 6 です。
より良い方法は、範囲を正方形の中間で間隔に分割することです。したがって、25 から 36 の中間 (30.5) までの数値は 5 と推定し、30.5 より大きく 36 までの数値は 6 と推定します。 [注 3] この手順では、掛け算表から 2 つの積の中間の境界数を見つけるために少しの計算を行うだけです。次に、境界の参照表を示します。
最後の演算は推定値 k に10の累乗を2で割った値を掛けることです。つまり 、
S
=
a
⋅
10
2
n
{\displaystyle S=a\cdot 10^{2n}}
S
≈
k
⋅
10
n
{\displaystyle {\sqrt {S}}\approx k\cdot 10^{n}}
この方法では、最適な最初の桁に丸められるため、暗黙的に 1 桁の精度が得られます。
この方法は、ほとんどの場合、被演算子を囲む最も近い正方形の間を補間することで、3桁の有効数字まで拡張できます。 の場合 、 はほぼkプラス分数であり、 a と k 2 の差を 2つの正方形の差で割ったものです。
ここで
k
2
≤
a
<
(
k
+
1
)
2
{\displaystyle k^{2}\leq a<(k+1)^{2}}
a
{\displaystyle {\sqrt {a}}}
a
≈
k
+
R
{\displaystyle {\sqrt {a}}\approx k+R}
R
=
(
a
−
k
2
)
(
k
+
1
)
2
−
k
2
{\displaystyle R={\frac {(a-k^{2})}{(k+1)^{2}-k^{2}}}}
最終的な演算は、上記のように、結果に 10 の累乗を 2 で割った値を掛けることです。
S
=
a
⋅
10
n
≈
(
k
+
R
)
⋅
10
n
{\displaystyle {\sqrt {S}}={\sqrt {a}}\cdot 10^{n}\approx (k+R)\cdot 10^{n}}
k は 10 進数で、 R は 10 進数に変換する必要がある分数です。通常、分子には 1 桁、分母には 1 桁または 2 桁しかないため、10 進数への変換は頭の中で行うことができます。
例: 75 の平方根を求めます。75 = 75 × 10 2 · 0 なので、 a は 75、 n は 0 です。九九から、仮数の平方根は 8 × 8 は 64 ですが、 9 × 9 は 81 で大きすぎるため、 8 の小数点数でなければなりません。 k は 8 です。 は R の 10 進数表現です 。分数 R は、分子が 75 - k 2 = 11、分母が 81 - k 2 = 17 です。11/17 は 12/18 より少し小さいので、これは 2/3 または .67 なので、 .66 と推測します (ここでは推測しても問題ありません。誤差は非常に小さいです)。したがって、推定値は 8 + .66 = 8.66 です。 √ 75 を 3 桁有効数字にすると 8.66 となるため、推定値は 3 桁有効数字まで正確です。この方法を使用した推定値はすべて正確であるとは限りませんが、近い値になります。
バイナリ推定
2進数体系 で作業する場合 (コンピュータ内部で行われるように)、 と表すと 、 平方根 は 次のように推定できる。
S
{\displaystyle S}
a
×
2
2
n
{\displaystyle a\times 2^{2n}}
0.1
2
≤
a
<
10
2
{\displaystyle 0.1_{2}\leq a<10_{2}}
S
=
a
×
2
n
{\displaystyle {\sqrt {S}}={\sqrt {a}}\times 2^{n}}
S
≈
(
0.485
+
0.485
⋅
a
)
⋅
2
n
{\displaystyle {\sqrt {S}}\approx (0.485+0.485\cdot a)\cdot 2^{n}}
これは、3 つの重要な数字の係数に対する最小二乗回帰直線です。 =2 での最大絶対誤差は 0.0408 、 =1 での最大相対誤差は 3.0% です。計算上便利な丸め推定値 (係数が 2 の累乗であるため) は次のようになります。
a
{\displaystyle {\sqrt {a}}}
a
{\displaystyle a}
a
{\displaystyle a}
S
≈
(
0.5
+
0.5
⋅
a
)
⋅
2
n
{\displaystyle {\sqrt {S}}\approx (0.5+0.5\cdot a)\cdot 2^{n}}
[注4]
最大絶対誤差は2で0.086、最大相対誤差は a = 0.5 および a = 2.0 で6.1%です。
の場合 、バイナリ近似は になります 。なので、推定値の絶対誤差は 19、相対誤差は 5.3% になります。 相対誤差は 1/2 4 より少し小さいので 、推定値は 4 ビット以上まで良好です。
S
=
125348
=
1
1110
1001
1010
0100
2
=
1.1110
1001
1010
0100
2
×
2
16
{\displaystyle S=125348=1\;1110\;1001\;1010\;0100_{2}=1.1110\;1001\;1010\;0100_{2}\times 2^{16}\,}
S
≈
(
0.5
+
0.5
⋅
a
)
⋅
2
8
=
1.0111
0100
1101
0010
2
⋅
1
0000
0000
2
=
1.456
⋅
256
=
372.8
{\displaystyle {\sqrt {S}}\approx (0.5+0.5\cdot a)\cdot 2^{8}=1.0111\;0100\;1101\;0010_{2}\cdot 1\;0000\;0000_{2}=1.456\cdot 256=372.8}
125348
=
354.0
{\displaystyle {\sqrt {125348}}=354.0}
の上位 8 ビットをテーブル検索することで、8 ビットまでの良好な値 の推定値を取得できます 。ただし、ほとんどの浮動小数点表現では上位ビットは暗黙的であり、8 の下位ビットは丸められる必要があることに注意してください。テーブルは、計算済みの 8 ビット平方根値の 256 バイトです。たとえば、 1.8515625 10 を表すインデックス 11101101 2 の場合、エントリは 10101110 2で、これは 1.8515625 10 の平方根を 8 ビット精度 (2 桁以上の 10 進数) で表した 1.359375 10 を表します 。
a
{\displaystyle a}
a
{\displaystyle a}
ヘロン法
近似値を求める 最初の明示的な アルゴリズムは 、1世紀のギリシャの数学者 アレクサンドリアのヘロン が 西暦60年 の著書 『計量学』 でその方法を説明したことにちなんで、ヘロン法 と呼ばれています 。 バビロニア法 とも呼ばれますが (斜辺を近似するバビロニア法と混同しないように注意)、バビロニア人がこの方法を知っていたという証拠はありません。
S
{\displaystyle \ {\sqrt {S~}}\ }
正の実数 が与えられたとき 、 x 0 > 0 を 任意の正の初期推定値とする。ヘロン法は、
所望の精度が達成されるまで繰り返し計算を行う。この式で定義される数列は 次のように収束する。
S
{\displaystyle S}
x
n
+
1
=
1
2
(
x
n
+
S
x
n
)
,
{\displaystyle x_{n+1}={\frac {1}{2}}\left(x_{n}+{\frac {S}{x_{n}}}\right),}
(
x
0
,
x
1
,
x
2
,
x
3
,
…
)
{\displaystyle \ {\bigl (}\ x_{0},\ x_{1},\ x_{2},\ x_{3},\ \ldots \ {\bigr )}\ }
lim
n
→
∞
x
n
=
S
.
{\displaystyle \ \lim _{n\to \infty }x_{n}={\sqrt {S~}}~.}
これは、ニュートン法を 使用してを解くこと と同じです 。このアルゴリズムは 2 次収束します 。つまり、 の正しい桁の数は、 各反復ごとにほぼ 2 倍になります。
x
2
−
S
=
0
{\displaystyle x^{2}-S=0}
x
n
{\displaystyle x_{n}}
導出
基本的な考え方は、 が非負の実数の平方根に対して過大評価されている場合 は が過小評価され、その逆も同様であるため、これら 2 つの数値の平均はより適切な近似値を提供すると合理的に期待できるというものです (ただし、この主張の正式な証明は 算術平均と幾何平均の不等式に依存しており、 平方根 に関する記事で述べたように、この平均は常に平方根に対して過大評価されるため 、収束が保証されます)。
x
{\displaystyle \ x\ }
S
{\displaystyle \ S\ }
S
x
{\displaystyle \ {\tfrac {\ S\ }{x}}\ }
より正確には、 が の初期推定値であり 、が 推定値の誤差である場合 、二項式を次のように展開することができます。
そして誤差項を解くと、
x
{\displaystyle \ x\ }
S
{\displaystyle \ {\sqrt {S~}}\ }
ε
{\displaystyle \ \varepsilon \ }
S
=
(
x
+
ε
)
2
,
{\displaystyle \ S=\left(x+\varepsilon \right)^{2}\ ,}
(
x
+
ε
)
2
=
x
2
+
2
x
ε
+
ε
2
{\displaystyle \ {\bigl (}\ x+\varepsilon \ {\bigr )}^{2}=x^{2}+2x\varepsilon +\varepsilon ^{2}}
ε
=
S
−
x
2
2
x
+
ε
≈
S
−
x
2
2
x
,
{\displaystyle \varepsilon ={\frac {\ S-x^{2}\ }{\ 2x+\varepsilon \ }}\approx {\frac {\ S-x^{2}\ }{2x}}\ ,}
もしそうであれば
ε
≪
x
{\displaystyle \ \varepsilon \ll x~}
したがって、誤差を補正し、古い推定値を次のように更新することができます
。計算された誤差は正確ではなかったため、これは実際の答えではありませんが、次の修正ラウンドで使用する新しい推定値になります。更新プロセスは、必要な精度が得られるまで繰り返されます。
x
+
ε
≈
x
+
S
−
x
2
2
x
=
S
+
x
2
2
x
=
S
x
+
x
2
≡
x
r
e
v
i
s
e
d
.
{\displaystyle \ x+\varepsilon \ \approx \ x+{\frac {\ S-x^{2}\ }{2x}}\ =\ {\frac {\ S+x^{2}\ }{2x}}\ =\ {\frac {\ {\frac {S}{\ x\ }}+x\ }{2}}\ \equiv \ x_{\mathsf {revised}}~.}
このアルゴリズムはp 進数 でも同様に機能しますが、実数の平方根を p 進数の平方根と同一視するためには使用できません。たとえば、この方法を使用すると 、実数では +3 に収束しますが、 2 進数では
-3 に収束する有理数列を作成できます。
例
を6桁の有効数字で 計算するには 、上記の概算方法を使用して
S
{\displaystyle \ {\sqrt {S~}}\ }
S
=
125348
,
{\displaystyle \ S=125348\ ,}
x
0
=
6
⋅
10
2
=
600.000
x
1
=
1
2
(
x
0
+
S
x
0
)
=
1
2
(
600.000
+
125348
600.000
)
=
404.457
x
2
=
1
2
(
x
1
+
S
x
1
)
=
1
2
(
404.457
+
125348
404.457
)
=
357.187
x
3
=
1
2
(
x
2
+
S
x
2
)
=
1
2
(
357.187
+
125348
357.187
)
=
354.059
x
4
=
1
2
(
x
3
+
S
x
3
)
=
1
2
(
354.059
+
125348
354.059
)
=
354.045
x
5
=
1
2
(
x
4
+
S
x
4
)
=
1
2
(
354.045
+
125348
354.045
)
=
354.045
{\displaystyle {\begin{aligned}{\begin{array}{rlll}x_{0}&=6\cdot 10^{2}&&=600.000\\[0.3em]x_{1}&={\frac {\ 1\ }{2}}\left(x_{0}+{\frac {S}{\;x_{0}\ }}\right)&={\frac {\ 1\ }{2}}\left(600.000+{\frac {\ 125348\ }{600.000}}\right)&=404.457\\[0.3em]x_{2}&={\frac {\ 1\ }{2}}\left(x_{1}+{\frac {S}{\;x_{1}\ }}\right)&={\frac {\ 1\ }{2}}\left(404.457+{\frac {\ 125348\ }{404.457}}\right)&=357.187\\[0.3em]x_{3}&={\frac {\ 1\ }{2}}\left(x_{2}+{\frac {S}{\;x_{2}\ }}\right)&={\frac {\ 1\ }{2}}\left(357.187+{\frac {\ 125348\ }{357.187}}\right)&=354.059\\[0.3em]x_{4}&={\frac {\ 1\ }{2}}\left(x_{3}+{\frac {S}{\;x_{3}\ }}\right)&={\frac {\ 1\ }{2}}\left(354.059+{\frac {\ 125348\ }{354.059}}\right)&=354.045\\[0.3em]x_{5}&={\frac {\ 1\ }{2}}\left(x_{4}+{\frac {S}{\;x_{4}\ }}\right)&={\frac {\ 1\ }{2}}\left(354.045+{\frac {\ 125348\ }{354.045}}\right)&=354.045\ \end{array}}\end{aligned}}}
したがって 小数点以下3桁までです。
125348
≈
354.045
{\displaystyle \ {\sqrt {125348~}}\approx 354.045\ }
収束
異なる初期推定値に対して100 の平方根を求めるヘロン法の収束速度を比較した半対数グラフ 。負の推定値は負の根に収束し、正の推定値は正の根に収束します。根に近い値ほど収束が速く、すべての近似値は過大評価であることに注意してください。SVG ファイルでは、グラフの上にマウスを移動すると、そのポイントが表示されます。
と仮定すると、 任意の自然数に対して、 相対 誤差が 次のよう に定義され
、
x
0
>
0
a
n
d
S
>
0
.
{\displaystyle \ x_{0}>0~~{\mathsf {and}}~~S>0~.}
n
:
x
n
>
0
.
{\displaystyle \ n:x_{n}>0~.}
x
n
{\displaystyle \ x_{n}\ }
ε
n
=
x
n
S
−
1
>
−
1
{\displaystyle \ \varepsilon _{n}={\frac {~x_{n}\ }{\ {\sqrt {S~}}\ }}-1>-1\ }
x
n
=
S
⋅
(
1
+
ε
n
)
.
{\displaystyle \ x_{n}={\sqrt {S~}}\cdot \left(1+\varepsilon _{n}\right)~.}
すると、
ε
n
+
1
=
ε
n
2
2
(
1
+
ε
n
)
≥
0
.
{\displaystyle \ \varepsilon _{n+1}={\frac {\varepsilon _{n}^{2}}{2(1+\varepsilon _{n})}}\geq 0~.}
したがって
、収束が保証され、 二次方程式 となります。
ε
n
+
2
≤
min
{
ε
n
+
1
2
2
,
ε
n
+
1
2
}
{\displaystyle \ \varepsilon _{n+2}\leq \min \left\{\ {\frac {\ \varepsilon _{n+1}^{2}\ }{2}},{\frac {\ \varepsilon _{n+1}\ }{2}}\ \right\}\ }
収束の最悪のケース
上記の大まかな推定をバビロニア方式で使用する場合、最も精度の低いケースは昇順で次のようになります。
S
=
1
;
x
0
=
2
;
x
1
=
1.250
;
ε
1
=
0.250
.
S
=
10
;
x
0
=
2
;
x
1
=
3.500
;
ε
1
<
0.107
.
S
=
10
;
x
0
=
6
;
x
1
=
3.833
;
ε
1
<
0.213
.
S
=
100
;
x
0
=
6
;
x
1
=
11.333
;
ε
1
<
0.134
.
{\displaystyle {\begin{aligned}S&=\ 1\ ;&x_{0}&=\ 2\ ;&x_{1}&=\ 1.250\ ;&\varepsilon _{1}&=\ 0.250~.\\S&=\ 10\ ;&x_{0}&=\ 2\ ;&x_{1}&=\ 3.500\ ;&\varepsilon _{1}&<\ 0.107~.\\S&=\ 10\ ;&x_{0}&=\ 6\ ;&x_{1}&=\ 3.833\ ;&\varepsilon _{1}&<\ 0.213~.\\S&=\ 100\ ;&x_{0}&=\ 6\ ;&x_{1}&=\ 11.333\ ;&\varepsilon _{1}&<\ 0.134~.\end{aligned}}}
いずれにせよ、
ε
1
≤
2
−
2
.
ε
2
<
2
−
5
<
10
−
1
.
ε
3
<
2
−
11
<
10
−
3
.
ε
4
<
2
−
23
<
10
−
6
.
ε
5
<
2
−
47
<
10
−
14
.
ε
6
<
2
−
95
<
10
−
28
.
ε
7
<
2
−
191
<
10
−
57
.
ε
8
<
2
−
383
<
10
−
115
.
{\displaystyle {\begin{aligned}\varepsilon _{1}&\leq 2^{-2}.\\\varepsilon _{2}&<2^{-5}<10^{-1}~.\\\varepsilon _{3}&<2^{-11}<10^{-3}~.\\\varepsilon _{4}&<2^{-23}<10^{-6}~.\\\varepsilon _{5}&<2^{-47}<10^{-14}~.\\\varepsilon _{6}&<2^{-95}<10^{-28}~.\\\varepsilon _{7}&<2^{-191}<10^{-57}~.\\\varepsilon _{8}&<2^{-383}<10^{-115}~.\end{aligned}}}
丸め誤差により収束が遅くなります。重大な丸め誤差を回避するために、計算対象
の必要な精度よりも少なくとも 1 桁多く残しておくことをお勧めします。
x
n
{\displaystyle \ x_{n}\ }
バクシャリ法
平方根の近似値を求めるこの方法は、 バクシャーリ写本 と呼ばれる古代 インドの写本に記載されています。これは、 x 0 から始まるバビロニア法の2回の反復に相当します 。したがって、このアルゴリズムは4次収束します。つまり、近似値の正しい桁の数は、反復ごとにほぼ4倍になります。 現代の表記法を使用した元の表現は次のとおりです。 を計算するには 、 を の初期近似値とします 。次に、次のように繰り返します。
S
{\displaystyle {\sqrt {S}}}
x
0
2
{\displaystyle x_{0}^{2}}
S
{\displaystyle S}
a
n
=
S
−
x
n
2
2
x
n
,
b
n
=
x
n
+
a
n
,
x
n
+
1
=
b
n
−
a
n
2
2
b
n
=
(
x
n
+
a
n
)
−
a
n
2
2
(
x
n
+
a
n
)
.
{\displaystyle {\begin{aligned}a_{n}&={\frac {S-x_{n}^{2}}{2x_{n}}},\\b_{n}&=x_{n}+a_{n},\\x_{n+1}&=b_{n}-{\frac {a_{n}^{2}}{2b_{n}}}=(x_{n}+a_{n})-{\frac {a_{n}^{2}}{2(x_{n}+a_{n})}}.\end{aligned}}}
これを使って、整数から始めて平方根の有理近似値を構築することができます。が に近い 整数で 、 が 絶対値が最小となる差である場合、最初の反復は次のように記述できます。
x
0
=
N
{\displaystyle x_{0}=N}
N
2
{\displaystyle N^{2}}
S
{\displaystyle S}
d
=
S
−
N
2
{\displaystyle d=S-N^{2}}
S
≈
N
+
d
2
N
−
d
2
8
N
3
+
4
N
d
=
8
N
4
+
8
N
2
d
+
d
2
8
N
3
+
4
N
d
=
N
4
+
6
N
2
S
+
S
2
4
N
3
+
4
N
S
=
N
2
(
N
2
+
6
S
)
+
S
2
4
N
(
N
2
+
S
)
.
{\displaystyle {\sqrt {S}}\approx N+{\frac {d}{2N}}-{\frac {d^{2}}{8N^{3}+4Nd}}={\frac {8N^{4}+8N^{2}d+d^{2}}{8N^{3}+4Nd}}={\frac {N^{4}+6N^{2}S+S^{2}}{4N^{3}+4NS}}={\frac {N^{2}(N^{2}+6S)+S^{2}}{4N(N^{2}+S)}}.}
バクシャリ法は分数根を含む任意の根の計算に一般化できる。
例
バビロニア法と同じ例を使って、 最初の反復では次のようになる。
S
=
125348.
{\displaystyle S=125348.}
x
0
=
600
a
0
=
125348
−
600
2
2
×
600
=
−
195.543
b
0
=
600
+
(
−
195.543
)
=
404.456
x
1
=
404.456
−
(
−
195.543
)
2
2
×
404.456
=
357.186
{\displaystyle {\begin{aligned}x_{0}&=600\\[1ex]a_{0}&={\frac {125348-600^{2}}{2\times 600}}&&=&-195.543\\[1ex]b_{0}&=600+(-195.543)&&=&404.456\\[1ex]x_{1}&=404.456-{\frac {(-195.543)^{2}}{2\times 404.456}}&&=&357.186\end{aligned}}}
同様に2回目の反復では
a
1
=
125348
−
357.186
2
2
×
357.186
=
−
3.126
b
1
=
357.186
+
(
−
3.126
)
=
354.060
x
2
=
354.06
−
(
−
3.1269
)
2
2
×
354.06
=
354.046
{\displaystyle {\begin{aligned}a_{1}&={\frac {125348-357.186^{2}}{2\times 357.186}}&&=&-3.126\\[1ex]b_{1}&=357.186+(-3.126)&&=&354.060\\[1ex]x_{2}&=354.06-{\frac {(-3.1269)^{2}}{2\times 354.06}}&&=&354.046\end{aligned}}}
桁ごとの計算
これは、数列内の平方根の各桁を求める方法です。この方法は 二項定理 に基づいており、基本的には逆アルゴリズムで解くものです 。バビロニア法よりも遅いですが、いくつかの利点があります。
(
x
+
y
)
2
=
x
2
+
2
x
y
+
y
2
{\displaystyle (x+y)^{2}=x^{2}+2xy+y^{2}}
手動で計算する方が簡単になります。
見つかったルートのすべての数字は正しいことが分かっています。つまり、後で変更する必要はありません。
平方根の展開が終了している場合、アルゴリズムは最後の桁が見つかった時点で終了します。したがって、これは与えられた整数が 平方数 であるかどうかを確認するために使用できます。
このアルゴリズムはどの 基数 でも機能しますが、当然ながら、その進行方法は選択された基数によって異なります。
デメリットは次のとおりです。
より高い根では管理できなくなります。
この方法では、不正確な推測や部分計算は許容されません。このようなエラーがあると、結果の次の桁がすべて間違ってしまいます。これは、近似エラーを自己修正する ニュートン法 とは異なります。
桁ごとの計算は理論上は十分効率的ですが、ソフトウェア実装にはコストがかかりすぎます。各反復には大きな数字が含まれ、より多くのメモリが必要になりますが、答えは正しい桁 1 つ分だけ進むだけです。したがって、アルゴリズムは桁が増えるごとに時間がかかります。
ネイピアの骨には、 このアルゴリズムの実行を支援する機能が含まれています。シフト n 乗根アルゴリズムは、この方法を一般化したものです。
基本原則
まず、数S の平方根を求めるケースを考えます。これは、10 を底とする 2 桁の数 XY の平方です 。ここで、 X は 10 の位、 Y は 1 の位です。具体的には、
S は 3 桁または 4 桁の 10 進数で構成されます。
S
=
(
10
X
+
Y
)
2
=
100
X
2
+
20
X
Y
+
Y
2
.
{\displaystyle S=\left(10X+Y\right)^{2}=100X^{2}+20XY+Y^{2}.}
桁ごとのアルゴリズムを開始するために、 S の桁を右から順に 2 桁ずつ 2 つのグループに分割します。つまり、最初のグループは 1 桁または 2 桁になります。次に、 Xの値を、 X 2 が 最初のグループ以下となる
最大の桁として決定します。次に、最初のグループと X 2 の差を計算し、それに 2 番目のグループを連結して 2 番目の反復を開始します。これは S から減算することと同じで 、 が残ります。 S' を 10 で割り、次に 2X で割り 、整数部分を保持して Y を推測します。 2X を 仮の Y と連結し、 Y を掛けます 。推測が正しければ、これは次を計算することと同じです。したがって、 S' と結果 の差である剰余は0 になります。結果が S' より大きい場合は 、推測値を 1 下げて、余りが 0 になるまで再試行します。これは答えが完全な平方根 XY である単純なケースなので、アルゴリズムはここで停止します。
100
X
2
{\displaystyle 100X^{2}}
S
′
=
20
X
Y
+
Y
2
{\displaystyle S'=20XY+Y^{2}}
(
10
(
2
X
)
+
Y
)
Y
=
20
X
Y
+
Y
2
=
S
′
,
{\displaystyle (10(2X)+Y)Y=20XY+Y^{2}=S',}
同じ考え方は、任意の平方根計算にも適用できます。Sの平方根を n 個の 正の数の和として表すと 、
S
=
(
a
1
+
a
2
+
a
3
+
⋯
+
a
n
)
2
.
{\displaystyle S=\left(a_{1}+a_{2}+a_{3}+\dots +a_{n}\right)^{2}.}
基本的な恒等式を繰り返し適用することで、
右辺の項は次のように展開できる。
(
x
+
y
)
2
=
x
2
+
2
x
y
+
y
2
,
{\displaystyle (x+y)^{2}=x^{2}+2xy+y^{2},}
(
a
1
+
a
2
+
a
3
+
⋯
+
a
n
)
2
=
a
1
2
+
2
a
1
a
2
+
a
2
2
+
2
(
a
1
+
a
2
)
a
3
+
a
3
2
+
⋯
+
a
n
−
1
2
+
2
(
∑
i
=
1
n
−
1
a
i
)
a
n
+
a
n
2
=
a
1
2
+
[
2
a
1
+
a
2
]
a
2
+
[
2
(
a
1
+
a
2
)
+
a
3
]
a
3
+
⋯
+
[
2
(
∑
i
=
1
n
−
1
a
i
)
+
a
n
]
a
n
.
{\displaystyle {\begin{aligned}&(a_{1}+a_{2}+a_{3}+\dotsb +a_{n})^{2}\\=&\,a_{1}^{2}+2a_{1}a_{2}+a_{2}^{2}+2(a_{1}+a_{2})a_{3}+a_{3}^{2}+\dots +a_{n-1}^{2}+2\left(\sum _{i=1}^{n-1}a_{i}\right)a_{n}+a_{n}^{2}\\=&\,a_{1}^{2}+[2a_{1}+a_{2}]a_{2}+[2(a_{1}+a_{2})+a_{3}]a_{3}+\dots +\left[2\left(\sum _{i=1}^{n-1}a_{i}\right)+a_{n}\right]a_{n}.\end{aligned}}}
この式では、s の値を順に推測することで平方根を求めることができます 。数値が すでに推測されているとすると、 上記の合計の右側の m 番目の項は、 によって与えられます。ここで 、 は、これまでに求められたおおよその平方根です。ここで、それぞれの新しい推測は
、 の後のすべての項の合計、つまり剰余であり 、
すべて に対してとなる 、初期化時の を満たす必要があります 。正確な平方根が求められた 場合、そうでない場合は、 の合計が 平方根の適切な近似値を与え、 は 近似誤差です。
a
i
{\displaystyle a_{i}}
a
1
,
…
,
a
m
−
1
{\displaystyle a_{1},\ldots ,a_{m-1}}
Y
m
=
[
2
P
m
−
1
+
a
m
]
a
m
,
{\displaystyle Y_{m}=\left[2P_{m-1}+a_{m}\right]a_{m},}
P
m
−
1
=
∑
i
=
1
m
−
1
a
i
{\textstyle P_{m-1}=\sum _{i=1}^{m-1}a_{i}}
a
m
{\displaystyle a_{m}}
X
m
=
X
m
−
1
−
Y
m
,
{\displaystyle X_{m}=X_{m-1}-Y_{m},}
X
m
{\displaystyle X_{m}}
Y
m
{\displaystyle Y_{m}}
X
m
≥
0
{\displaystyle X_{m}\geq 0}
1
≤
m
≤
n
,
{\displaystyle 1\leq m\leq n,}
X
0
=
S
.
{\displaystyle X_{0}=S.}
X
n
=
0
,
{\displaystyle X_{n}=0,}
a
i
{\displaystyle a_{i}}
X
n
{\displaystyle X_{n}}
例えば、10進数では、 は
プレースホルダー
で 、係数はです 。平方根計算の任意のm番目の段階で、これまでに求められた近似根 と合計項は 次のように与えられます。
S
=
(
a
1
⋅
10
n
−
1
+
a
2
⋅
10
n
−
2
+
⋯
+
a
n
−
1
⋅
10
+
a
n
)
2
,
{\displaystyle S=\left(a_{1}\cdot 10^{n-1}+a_{2}\cdot 10^{n-2}+\cdots +a_{n-1}\cdot 10+a_{n}\right)^{2},}
10
n
−
i
{\displaystyle 10^{n-i}}
a
i
∈
{
0
,
1
,
2
,
…
,
9
}
{\displaystyle a_{i}\in \{0,1,2,\ldots ,9\}}
P
m
−
1
{\displaystyle P_{m-1}}
Y
m
{\displaystyle Y_{m}}
P
m
−
1
=
∑
i
=
1
m
−
1
a
i
⋅
10
n
−
i
=
10
n
−
m
+
1
∑
i
=
1
m
−
1
a
i
⋅
10
m
−
i
−
1
,
{\displaystyle P_{m-1}=\sum _{i=1}^{m-1}a_{i}\cdot 10^{n-i}=10^{n-m+1}\sum _{i=1}^{m-1}a_{i}\cdot 10^{m-i-1},}
Y
m
=
[
2
P
m
−
1
+
a
m
⋅
10
n
−
m
]
a
m
⋅
10
n
−
m
=
[
20
∑
i
=
1
m
−
1
a
i
⋅
10
m
−
i
−
1
+
a
m
]
a
m
⋅
10
2
(
n
−
m
)
.
{\displaystyle Y_{m}=\left[2P_{m-1}+a_{m}\cdot 10^{n-m}\right]a_{m}\cdot 10^{n-m}=\left[20\sum _{i=1}^{m-1}a_{i}\cdot 10^{m-i-1}+a_{m}\right]a_{m}\cdot 10^{2(n-m)}.}
ここで、 の位の値は 10 の偶数乗なので、 任意の m 番目のステージで、
最初の項が である剰余 の最上位桁のペアのみを処理すれば済みます。以下のセクションでは、この手順を体系化します。
Y
m
{\displaystyle Y_{m}}
X
m
−
1
{\displaystyle X_{m-1}}
Y
m
{\displaystyle Y_{m}}
同様の方法を使用して、10 進数以外の記数法で平方根を計算できることは明らかです。たとえば、2 進数で桁ごとの平方根を求めることは、 の値が {0,1} のより小さな 2 進数セットから検索されるため、非常に効率的です。これにより、各段階で の値が の 場合 または の 場合の いずれかになるため、計算が高速になります 。 の可能な選択肢が 2 つしかないという事実は、計算の m 番目の段階で の値を決定するプロセスも 容易にします。これは、 について かどうかを確認するだけでよいためです。 この条件が満たされている場合は を取り、 そうでない場合は を取ります。 また、2 による乗算が左ビットシフトによって行われるという事実は、計算に役立ちます。
a
i
{\displaystyle a_{i}}
Y
m
{\displaystyle Y_{m}}
Y
m
=
0
{\displaystyle Y_{m}=0}
a
m
=
0
{\displaystyle a_{m}=0}
Y
m
=
2
P
m
−
1
+
1
{\displaystyle Y_{m}=2P_{m-1}+1}
a
m
=
1
{\displaystyle a_{m}=1}
a
m
{\displaystyle a_{m}}
a
m
{\displaystyle a_{m}}
Y
m
≤
X
m
−
1
{\displaystyle Y_{m}\leq X_{m-1}}
a
m
=
1.
{\displaystyle a_{m}=1.}
a
m
=
1
{\displaystyle a_{m}=1}
a
m
=
0.
{\displaystyle a_{m}=0.}
10進数(10進数)
元の数字を小数形式で書きます。数字は長除法の アルゴリズムに似た形式で書きます 。長除法の場合と同様に、ルートは上の行に書きます。次に、小数点から始めて左と右の両方に数字をペアに分けます。ルートの小数点は、平方の小数点の上にあります。平方の各数字ペアの上には、ルートの 1 つの数字が表示されます。
左端の数字のペアから始めて、各ペアに対して次の手順を実行します。
左から始めて、まだ使用されていない最上位 (左端) の数字のペアを下ろし (すべての数字が使用されている場合は、「00」と書きます)、前の手順の余りの右側に書き込みます (最初の手順では余りはありません)。つまり、余りに 100 を掛けて、2 つの数字を加算します。これが 現在の値 c になります。
次のようにp 、 y 、 x を 求めます 。
小数点を無視し、 これまでに求めた根の部分 を p とします。(最初のステップでは、 p = 0 です。)
となる 最大の数字 x を決定します。新しい変数 y = x (20 p + x ) を使用します。
x
(
20
p
+
x
)
≤
c
{\displaystyle x(20p+x)\leq c}
注: 20 p + x は 単に p を 2 倍して、右側に 数字 xを追加したものです。
注: x は、 c /(20· p ) を推測し、 y を試算して、必要に応じて x を 上下に 調整する ことで見つけることができます。
その数字を ルートの次の数字、つまり先ほど下ろした平方数の 2 つの数字の上に置きます。したがって、次の p は 古い p の 10 倍に x を 加えたものになります。
x
{\displaystyle x}
c から y を 減算して 新しい剰余を作成します。
余りがゼロで、下げる桁がもうない場合は、アルゴリズムは終了します。それ以外の場合は、ステップ 1 に戻ってもう一度繰り返します。
例
152.2756 の平方根を求めます。
1 2. 3 4
/
\/ 01 52.27 56
01 1*1 <= 1 < 2*2 x=1
01 y = x*x = 1*1 = 1
00 52 22*2 <= 52 < 23*3 x=2
00 44 y = (20+x)*x = 22*2 = 44
08 27 243*3 <= 827 < 244*4 x=3
07 29 y = (240+x)*x = 243*3 = 729
98 56 2464*4 <= 9856 < 2465*5 x=4
98 56 y = (2460+x)*x = 2464*4 = 9856
00 00 アルゴリズム終了: 答え=12.34
2進法(基数2)
このセクションでは、上記の桁ごとの計算セクションの形式論を使用しますが、わずかに変更して、 を 各 またはとともに使用します 。 から まで の
すべての を反復し、 値が決定された すべての の合計で ある近似解 を構築します。 が または に 等しい かどうかを
判断するために 、 とします 。 (つまり、 を含む近似解の平方が ターゲットの平方を超えない場合)の場合は 、それ以外の場合 は および です 。各ステップで
平方することを避けるために 、差を保存し、 で を 設定することで増分的に更新します 。最初は、 で 最大の を
設定します 。
N
2
=
(
a
n
+
⋯
+
a
0
)
2
{\displaystyle N^{2}=(a_{n}+\dotsb +a_{0})^{2}}
a
m
=
2
m
{\displaystyle a_{m}=2^{m}}
a
m
=
0
{\displaystyle a_{m}=0}
2
m
{\displaystyle 2^{m}}
2
n
{\displaystyle 2^{n}}
2
0
{\displaystyle 2^{0}}
P
m
=
a
n
+
a
n
−
1
+
…
+
a
m
{\displaystyle P_{m}=a_{n}+a_{n-1}+\ldots +a_{m}}
a
i
{\displaystyle a_{i}}
a
m
{\displaystyle a_{m}}
2
m
{\displaystyle 2^{m}}
0
{\displaystyle 0}
P
m
=
P
m
+
1
+
2
m
{\displaystyle P_{m}=P_{m+1}+2^{m}}
P
m
2
≤
N
2
{\displaystyle P_{m}^{2}\leq N^{2}}
2
m
{\displaystyle 2^{m}}
a
m
=
2
m
{\displaystyle a_{m}=2^{m}}
a
m
=
0
{\displaystyle a_{m}=0}
P
m
=
P
m
+
1
{\displaystyle P_{m}=P_{m+1}}
P
m
{\displaystyle P_{m}}
X
m
=
N
2
−
P
m
2
{\displaystyle X_{m}=N^{2}-P_{m}^{2}}
X
m
=
X
m
+
1
−
Y
m
{\displaystyle X_{m}=X_{m+1}-Y_{m}}
Y
m
=
P
m
2
−
P
m
+
1
2
=
2
P
m
+
1
a
m
+
a
m
2
{\displaystyle Y_{m}=P_{m}^{2}-P_{m+1}^{2}=2P_{m+1}a_{m}+a_{m}^{2}}
a
n
=
P
n
=
2
n
{\displaystyle a_{n}=P_{n}=2^{n}}
n
{\displaystyle n}
(
2
n
)
2
=
4
n
≤
N
2
{\displaystyle (2^{n})^{2}=4^{n}\leq N^{2}}
追加の最適化として、がゼロでない 場合の 2 つの項である と を 別々の変数 、に格納します 。
P
m
+
1
2
m
+
1
{\displaystyle P_{m+1}2^{m+1}}
(
2
m
)
2
{\displaystyle (2^{m})^{2}}
Y
m
{\displaystyle Y_{m}}
a
m
{\displaystyle a_{m}}
c
m
{\displaystyle c_{m}}
d
m
{\displaystyle d_{m}}
c
m
=
P
m
+
1
2
m
+
1
{\displaystyle c_{m}=P_{m+1}2^{m+1}}
d
m
=
(
2
m
)
2
{\displaystyle d_{m}=(2^{m})^{2}}
Y
m
=
{
c
m
+
d
m
if
a
m
=
2
m
0
if
a
m
=
0
{\displaystyle Y_{m}={\begin{cases}c_{m}+d_{m}&{\text{if }}a_{m}=2^{m}\\0&{\text{if }}a_{m}=0\end{cases}}}
c
m
{\displaystyle c_{m}}
各ステップで効率的に更新できます
。
d
m
{\displaystyle d_{m}}
c
m
−
1
=
P
m
2
m
=
(
P
m
+
1
+
a
m
)
2
m
=
P
m
+
1
2
m
+
a
m
2
m
=
{
c
m
/
2
+
d
m
if
a
m
=
2
m
c
m
/
2
if
a
m
=
0
{\displaystyle c_{m-1}=P_{m}2^{m}=(P_{m+1}+a_{m})2^{m}=P_{m+1}2^{m}+a_{m}2^{m}={\begin{cases}c_{m}/2+d_{m}&{\text{if }}a_{m}=2^{m}\\c_{m}/2&{\text{if }}a_{m}=0\end{cases}}}
d
m
−
1
=
d
m
4
{\displaystyle d_{m-1}={\frac {d_{m}}{4}}}
注意してください:
これは以下の関数で返される最終結果です。
c
−
1
=
P
0
2
0
=
P
0
=
N
,
{\displaystyle c_{-1}=P_{0}2^{0}=P_{0}=N,}
このアルゴリズムのC言語での実装:
int32_t isqrt ( int32_t n ) {
assert (( "sqrt 入力は負でない必要があります" 、 n > 0 ));
// X_(n+1)
int32_t x = n ;
// c_n
int32_t c = 0 ;
// 4 の最大の累乗 <= n から始まる d_n
int32_t d = 1 << 30 ; // 上から2番目のビットが設定されます。
// ((unsigned) INT32_MAX + 1) / 2 と同じです。
( d > n ) の間 {
d >>= 2 ;
}
// dₙ … d₀の場合
( d != 0 ) の間 {
if ( x >= c + d ) { // X_(m+1) ≥ Y_m の場合、a_m = 2^m
x -= c + d ; // X_m = X_(m+1) - Y_m
c = ( c >> 1 ) + d ; // c_(m-1) = c_m/2 + d_m (a_m は 2^m)
}
それ以外 {
c >>= 1 ; // c_(m-1) = c_m/2 (aₘ は 0)
}
d >>= 2 ; // d_(m-1) = d_m/4
}
c を 返す ; // c_(-1)
}
2進数や10進数、その他の基数でのより高速なアルゴリズムは、ルックアップテーブルを使用することで実現できます。つまり、より多くのストレージスペースと引き換えに 実行時間を短縮することができ ます。
指数関数的アイデンティティ
ポケット電卓 には通常、 指数関数 と 自然対数 を計算するための優れたルーチンが実装されており、次に対数 ( ) と指数 ( ) の特性を使用して見つかった恒等式を使用して S の平方根を計算します。 [ 引用が必要 ]
分数の分母は n乗根に対応します。上記のケースでは分母は 2 なので、この式は平方根を求めることを指定します。 対数表 や 計算尺 を使用して平方根を計算するときにも、同じ恒等式が使用されます 。
ln
x
n
=
n
ln
x
{\displaystyle \ln x^{n}=n\ln x}
e
ln
x
=
x
{\displaystyle e^{\ln x}=x}
S
=
e
1
2
ln
S
.
{\displaystyle {\sqrt {S}}=e^{{\frac {1}{2}}\ln S}.}
2変数反復法
この方法は の平方根を求めるのに適用でき 、 は に対して最もよく収束します 。ただし、これはコンピュータベースの計算では実際の制限にはなりません。基数 2 の浮動小数点および固定小数点表現では、 指数を変更するかシフトすることにより、それぞれ 4 の整数乗、したがって対応する 2 の累乗を乗算するのは簡単です。したがって、 は 範囲 に移動できます 。さらに、次の方法では一般的な除算は使用せず、2 の累乗による加算、減算、乗算、および除算のみを使用します。これらも実装が簡単です。この方法の欠点は、バビロニア法などの単一変数反復法とは対照的に、数値誤差が蓄積することです。
0
<
S
<
3
{\displaystyle 0<S<3\,\!}
S
≈
1
{\displaystyle S\approx 1}
S
{\displaystyle S\,\!}
S
{\displaystyle {\sqrt {S}}}
S
{\displaystyle S\,\!}
1
2
≤
S
<
2
{\textstyle {\tfrac {1}{2}}\leq S<2}
このメソッドの初期化ステップは、
反復ステップが
次に (while ) を読み取りながら行われます。
a
0
=
S
c
0
=
S
−
1
{\displaystyle {\begin{aligned}a_{0}&=S\\c_{0}&=S-1\end{aligned}}}
a
n
+
1
=
a
n
−
a
n
c
n
/
2
c
n
+
1
=
c
n
2
(
c
n
−
3
)
/
4
{\displaystyle {\begin{aligned}a_{n+1}&=a_{n}-a_{n}c_{n}/2\\c_{n+1}&=c_{n}^{2}(c_{n}-3)/4\end{aligned}}}
a
n
→
S
{\displaystyle a_{n}\to {\sqrt {S}}}
c
n
→
0
{\displaystyle c_{n}\to 0}
の収束は2 次式 であり、したがって の収束も 2 次式です。
c
n
{\displaystyle c_{n}\,\!}
a
n
{\displaystyle a_{n}\,\!}
この方法の証明は比較的簡単です。まず、 の反復定義を として書き直します 。
次に、 を帰納的に証明するのは簡単です
。したがって、 が 目的の結果に
収束することは、 が 0 に収束することによって保証され 、これは から導かれます 。
c
n
{\displaystyle c_{n}}
1
+
c
n
+
1
=
(
1
+
c
n
)
(
1
−
1
2
c
n
)
2
.
{\displaystyle 1+c_{n+1}=(1+c_{n})(1-{\tfrac {1}{2}}c_{n})^{2}.}
S
(
1
+
c
n
)
=
a
n
2
{\displaystyle S(1+c_{n})=a_{n}^{2}}
a
n
{\displaystyle a_{n}\,\!}
S
{\displaystyle {\sqrt {S}}}
c
n
{\displaystyle c_{n}\,\!}
−
1
<
c
0
<
2
{\displaystyle -1<c_{0}<2\,\!}
この方法は、1950年頃に MVウィルクス 、 DJホイーラー 、 S.ギル によって、世界初の電子計算機の一つである EDSAC で使用するために開発されました。 この方法は後に一般化され、平方根以外の計算も可能になりました。
逆平方根の反復法
以下は、 S の逆平方根を求める反復法です 。逆平方根 が見つかったら、 単純な乗算で を求めます。 これらの反復では乗算のみが行われ、除算は行われません。したがって、バビロニア法よりも高速です。ただし、安定していません。初期値が逆平方根に近くない場合、反復は逆平方根に収束するのではなく、そこから発散します。したがって、これらの方法を適用する前に、大まかな推定値でバビロニア法の反復を実行すると有利です。
1
/
S
{\displaystyle 1/{\sqrt {S}}}
S
{\displaystyle {\sqrt {S}}}
S
=
S
⋅
(
1
/
S
)
{\displaystyle {\sqrt {S}}=S\cdot (1/{\sqrt {S}})}
ニュートン法を この方程式に 適用すると 、ステップごとに 3 回の乗算を使用して 2 次収束する方法が生成されます。
(
1
/
x
2
)
−
S
=
0
{\displaystyle (1/x^{2})-S=0}
x
n
+
1
=
x
n
2
⋅
(
3
−
S
⋅
x
n
2
)
=
x
n
⋅
(
3
2
−
S
2
⋅
x
n
2
)
.
{\displaystyle x_{n+1}={\frac {x_{n}}{2}}\cdot (3-S\cdot x_{n}^{2})=x_{n}\cdot \left({\frac {3}{2}}-{\frac {S}{2}}\cdot x_{n}^{2}\right).}
もう1つの反復は、ハレー法 によって得られます。 これは、 2次のハウス ホルダー法です。これは 3次収束します が、反復ごとに5回の乗算が必要です。 [ 引用が必要 ] および
y
n
=
S
⋅
x
n
2
,
{\displaystyle y_{n}=S\cdot x_{n}^{2},}
x
n
+
1
=
x
n
8
⋅
(
15
−
y
n
⋅
(
10
−
3
⋅
y
n
)
)
=
x
n
⋅
(
15
8
−
y
n
⋅
(
10
8
−
3
8
⋅
y
n
)
)
.
{\displaystyle x_{n+1}={\frac {x_{n}}{8}}\cdot (15-y_{n}\cdot (10-3\cdot y_{n}))=x_{n}\cdot \left({\frac {15}{8}}-y_{n}\cdot \left({\frac {10}{8}}-{\frac {3}{8}}\cdot y_{n}\right)\right).}
固定小数点演算 を行う場合、3 倍の乗算と 8 倍の除算はシフトと加算を使用して実装できます。浮動小数点を使用する場合、 他のすべての定数を事前に 計算して調整することで、Halley 法を反復ごとに 4 回の乗算に減らすことができます 。
3
/
8
S
{\textstyle {\sqrt {3/8}}S}
y
n
=
3
8
S
⋅
x
n
2
,
{\displaystyle y_{n}={\sqrt {\frac {3}{8}}}S\cdot x_{n}^{2},}
x
n
+
1
=
x
n
⋅
(
15
8
−
y
n
⋅
(
25
6
−
y
n
)
)
.
{\displaystyle x_{n+1}=x_{n}\cdot \left({\frac {15}{8}}-y_{n}\cdot \left({\sqrt {\frac {25}{6}}}-y_{n}\right)\right).}
ゴールドシュミットのアルゴリズム
ゴールドシュミットのアルゴリズムは、ロバート・エリオット・ゴールドシュミットにちなんで名付けられた ゴールドシュミット除算 の拡張であり、 [11] [12] 平方根の計算に使用できます。一部のコンピュータでは、ゴールドシュミットのアルゴリズムを使用して、 とを同時に計算します 。ゴールドシュミットのアルゴリズムは、 融合乗算加算 命令とパイプライン浮動小数点ユニットまたは2つの独立した浮動小数点ユニットを備えたコンピュータで、ニュートン・ラプソン反復法より も高速に計算します。
S
{\displaystyle {\sqrt {S}}}
1
/
S
{\displaystyle 1/{\sqrt {S}}}
S
{\displaystyle {\sqrt {S}}}
ゴールドシュミットのアルゴリズムの最初の書き方は
b
0
=
S
{\displaystyle b_{0}=S}
Y
0
≈
1
/
S
{\displaystyle Y_{0}\approx 1/{\sqrt {S}}}
(通常はテーブル検索を使用)
y
0
=
Y
0
{\displaystyle y_{0}=Y_{0}}
x
0
=
S
y
0
{\displaystyle x_{0}=Sy_{0}}
が 1 に十分近くなるか、固定回数反復される
まで 、 を反復します
。反復は と
に収束します。 計算から との
いずれかを省略することも可能であり、両方が必要な場合は、 各反復で を計算するのではなく、最後に を使用できることに注意してください。
b
n
+
1
=
b
n
Y
n
2
Y
n
+
1
=
1
2
(
3
−
b
n
+
1
)
x
n
+
1
=
x
n
Y
n
+
1
y
n
+
1
=
y
n
Y
n
+
1
{\displaystyle {\begin{aligned}b_{n+1}&=b_{n}Y_{n}^{2}\\Y_{n+1}&={\tfrac {1}{2}}(3-b_{n+1})\\x_{n+1}&=x_{n}Y_{n+1}\\y_{n+1}&=y_{n}Y_{n+1}\end{aligned}}}
b
i
{\displaystyle b_{i}}
lim
n
→
∞
x
n
=
S
,
{\displaystyle \lim _{n\to \infty }x_{n}={\sqrt {S}},}
lim
n
→
∞
y
n
=
1
/
S
.
{\displaystyle \lim _{n\to \infty }y_{n}=1/{\sqrt {S}}.}
x
n
{\displaystyle x_{n}}
y
n
{\displaystyle y_{n}}
x
n
=
S
y
n
{\displaystyle x_{n}=Sy_{n}}
2番目の形式は、 融合乗算加算 演算を使用して始まります。
y
0
≈
1
/
S
{\displaystyle y_{0}\approx 1/{\sqrt {S}}}
(通常はテーブル検索を使用)
x
0
=
S
y
0
{\displaystyle x_{0}=Sy_{0}}
h
0
=
1
2
y
0
{\displaystyle h_{0}={\tfrac {1}{2}}y_{0}}
が0に十分近づくまで 、または一定回数の反復
を繰り返す
。これは収束し 、
r
n
=
0.5
−
x
n
h
n
x
n
+
1
=
x
n
+
x
n
r
n
h
n
+
1
=
h
n
+
h
n
r
n
{\displaystyle {\begin{aligned}r_{n}&=0.5-x_{n}h_{n}\\x_{n+1}&=x_{n}+x_{n}r_{n}\\h_{n+1}&=h_{n}+h_{n}r_{n}\end{aligned}}}
r
i
{\displaystyle r_{i}}
lim
n
→
∞
x
n
=
S
,
{\displaystyle \lim _{n\to \infty }x_{n}={\sqrt {S}},}
lim
n
→
∞
2
h
n
=
1
/
S
.
{\displaystyle \lim _{n\to \infty }2h_{n}=1/{\sqrt {S}}.}
テイラー級数
N が の近似値で ある場合、 平方根 関数の テイラー級数 を使用することでより良い近似値を求めることができます 。
S
{\displaystyle {\sqrt {S}}}
N
2
+
d
=
N
∑
n
=
0
∞
(
−
1
)
n
(
2
n
)
!
(
1
−
2
n
)
n
!
2
4
n
d
n
N
2
n
=
N
(
1
+
d
2
N
2
−
d
2
8
N
4
+
d
3
16
N
6
−
5
d
4
128
N
8
+
⋯
)
{\displaystyle {\sqrt {N^{2}+d}}=N\sum _{n=0}^{\infty }{\frac {(-1)^{n}(2n)!}{(1-2n)n!^{2}4^{n}}}{\frac {d^{n}}{N^{2n}}}=N\left(1+{\frac {d}{2N^{2}}}-{\frac {d^{2}}{8N^{4}}}+{\frac {d^{3}}{16N^{6}}}-{\frac {5d^{4}}{128N^{8}}}+\cdots \right)}
反復法であるため、 収束の順序は 使用される項の数に等しくなります。項が 2 つの場合、バビロニア法と同じです。項が 3 つの場合、各反復には Bakhshali 近似とほぼ同じ数の演算が必要ですが、収束は遅くなります。 [ 引用が必要 ]したがって、これは特に効率的な計算方法ではありません。収束率を最大化するには、 N を できるだけ小さくするよう
に 選択します。
|
d
|
N
2
{\displaystyle {\frac {|d|}{N^{2}}}\,}
連分数展開
実数の連分数 表現 は、その 10 進数または 2 進数展開の代わりに使用できます。この表現には、有理数 (完全な平方数ではない) の平方根が周期的に繰り返される展開を持つという特性があります。これは、有理数が 10 進数表記システムで繰り返し展開を持つのと同様です。
2 次無理数( a 、 b 、 c が整数である の 形の数 )、特に整数の平方根には、 周期的な連分数 があります。平方根の数値ではなく、 連分数 展開、つまり有理数近似を求めることが必要な場合もあります。 平方根を求める必要がある正の数を Sとします。次に、 a を 初期推定値として、 r を 剰余項とすると、次のように書くことができます。 であるため、 S の平方根は 次のように
表すことができます。
a
+
b
c
{\displaystyle {\frac {a+{\sqrt {b}}}{c}}}
S
=
a
2
+
r
.
{\displaystyle S=a^{2}+r.}
S
−
a
2
=
(
S
+
a
)
(
S
−
a
)
=
r
{\displaystyle S-a^{2}=({\sqrt {S}}+a)({\sqrt {S}}-a)=r}
S
=
a
+
r
a
+
S
.
{\displaystyle {\sqrt {S}}=a+{\frac {r}{a+{\sqrt {S}}}}.}
この式を分数の分母に
適用すると、
S
{\displaystyle {\sqrt {S}}}
S
=
a
+
r
a
+
(
a
+
r
a
+
S
)
=
a
+
r
2
a
+
r
a
+
S
.
{\displaystyle {\sqrt {S}}=a+{\frac {r}{a+(a+{\frac {r}{a+{\sqrt {S}}}})}}=a+{\frac {r}{2a+{\frac {r}{a+{\sqrt {S}}}}}}.}
コンパクト表記
連分数の分子/分母展開(左図参照)は、書き方もテキストフォーマットシステムに埋め込むのも面倒です。そのため、数学者は次のようないくつかの代替表記法を考案しました。 [14]
S
=
a
+
r
2
a
+
r
2
a
+
r
2
a
+
⋯
{\displaystyle {\sqrt {S}}=a+{\frac {r}{2a+}}\,{\frac {r}{2a+}}\,{\frac {r}{2a+}}\cdots }
全体を通すと 、さらに簡潔な表記法は次のようになる: [15]
連分数の繰り返し(非完全平方の平方根はすべてそうである)の場合、繰り返し部分は1回だけ表され、上線は上線部分の非終端繰り返しを示す: [16]
r
=
1
{\displaystyle r=1}
[
a
;
2
a
,
2
a
,
2
a
,
⋯
]
{\displaystyle [a;2a,2a,2a,\cdots ]}
[
a
;
2
a
¯
]
{\displaystyle [a;{\overline {2a}}]}
√ 2 の場合 、 の値は 1 なので、その表現は次のようになります。
a
{\displaystyle a}
[
1
;
2
¯
]
{\displaystyle [1;{\overline {2}}]}
この方法を続けると、 平方根の
一般化された連分数は次のように表される。
S
=
a
+
r
2
a
+
r
2
a
+
r
2
a
+
⋱
{\displaystyle {\sqrt {S}}=a+{\cfrac {r}{2a+{\cfrac {r}{2a+{\cfrac {r}{2a+\ddots }}}}}}}
このような分数 を評価して根を求める最初のステップは、希望する数の根と選択した分母の数を数値で代入することです。たとえば、標準形式では、は 1 であり、 √2 の場合は 1であるため、分母が3つの場合の数値連分数は次のようになります。
r
{\displaystyle r}
a
{\displaystyle a}
2
≈
1
+
1
2
+
1
2
+
1
2
{\displaystyle {\sqrt {2}}\approx 1+{\cfrac {1}{2+{\cfrac {1}{2+{\cfrac {1}{2}}}}}}}
ステップ 2 では、連分数を 1 分母ずつ下から上へ減算して、分子と分母が整数である有理分数を生成します。減算は次のように行われます (最初の 3 つの分母を取ります)。
1
+
1
2
+
1
2
+
1
2
=
1
+
1
2
+
1
5
2
=
1
+
1
2
+
2
5
=
1
+
1
12
5
=
1
+
5
12
=
17
12
{\displaystyle {\begin{aligned}1+{\cfrac {1}{2+{\cfrac {1}{2+{\cfrac {1}{2}}}}}}&=1+{\cfrac {1}{2+{\cfrac {1}{\frac {5}{2}}}}}\\&=1+{\cfrac {1}{2+{\cfrac {2}{5}}}}=1+{\cfrac {1}{\frac {12}{5}}}\\&=1+{\cfrac {5}{12}}={\frac {17}{12}}\end{aligned}}}
最後に (手順 3)、有理分数の分子を分母で割って、根のおおよその値を取得します。
これは 3 桁の精度に丸められます。
17
÷
12
=
1.42
{\displaystyle 17\div 12=1.42}
√ 2 の実際の値は 、3 桁の有効数字で 1.41 です。相対誤差は 0.17% なので、有理分数はほぼ 3 桁の精度で良好です。分母の数を増やすと、より正確な近似値が得られます。分母が 4 つになると分数 になり 、ほぼ 4 桁の精度で良好になります。
41
29
=
1.4137
{\displaystyle {\frac {41}{29}}=1.4137}
以下は、平方根、その単純な連分数、および 分母 99 までの
平方根の最初の項 ( 収束項と呼ばれる) の例です。
一般に、有理分数の分母が大きいほど、近似値は高くなります。また、連分数を切り捨てると、分母がその分数の分母以下の分数の根に最も近似する有理分数が得られることも示されています。たとえば、分母が 70 以下の分数は、 99/70 ほど √ 2 に近似できません。
浮動小数点表現に依存する近似値
数は 浮動小数点 形式で表され 、これは 科学的記数法 とも呼ばれます。平方根は で 、立方根や対数にも同様の式が適用されます。一見すると、これは単純さの向上ではありませんが、近似値のみが必要であると仮定すると、 桁違いの で十分です。次に、いくつかの累乗 p が奇数になることを認識します。したがって、3141.59 = 3.14159 × 10
m
×
b
p
{\displaystyle m\times b^{p}}
m
×
b
p
/
2
{\displaystyle {\sqrt {m}}\times b^{p/2}}
b
p
/
2
{\displaystyle b^{p/2}}
3 基数の分数乗を扱うのではなく、仮数部に基数を掛け、その乗数から1を引いて偶数にします。調整された表現は31.4159 × 10 2 なので平方根は √31.4159 × 10 となる。 1 .
調整された仮数の整数部が取られる場合、値は 1 から 99 までしか存在できず、これは 99 個の事前計算された平方根の表へのインデックスとして使用して推定を完了できます。基数 16 を使用するコンピューターではより大きな表が必要になりますが、基数 2 を使用するコンピューターでは 3 つのエントリのみが必要です。調整された仮数の整数部の可能なビットは 01 (べき乗が偶数なのでシフトはありません。 正規化された 浮動小数点数は常に 0 以外の上位桁を持つことを覚えておいてください) または、べき乗が奇数の場合は 10 または 11 で、これらは元の仮数の 最初の 2 ビットです。したがって、6.25 = 110.01 は 2 進数で 1.1001 × 2 2 に正規化され、偶数累乗なので 仮数のペアのビットは 01 になります。一方、.625 = 0.101 は 2 進数で 1.01 × 2 −1に正規化され、奇数累乗なので調整は 10.1 × 2 −2 になり、ペアのビットは 10 になります。累乗の下位ビットがペアの仮数の上位ビットに反映されていることに注意してください。偶数累乗の下位ビットは 0 で、調整された仮数は 0 から始まりますが、奇数累乗の下位ビットは 1 で、調整された仮数は 1 から始まります。したがって、累乗が半分になると、下位ビットがシフトされてペアの仮数の最初のビットになります。
エントリが 3 つだけのテーブルは、仮数部の追加ビットを組み込むことで拡大できます。ただし、コンピューターでは、テーブルに補間を計算するよりも、同等の結果をもたらすより単純な計算を見つける方がよい場合がよくあります。すべては、表現の形式の詳細と、数値の各部分にアクセスして操作するために使用できる操作に依存します。たとえば、 Fortran では 累乗を取得する関数が提供され EXPONENT(x)ています。適切な初期近似値を求めるために費やされた労力は、不適切な近似値を求めるために必要となる改良プロセスの追加の反復を回避することで回収されます。反復回数は少ないため (1 回の反復で除算、加算、および半分にする必要があります)、制約は厳格です。
多くのコンピュータは IEEE (または十分に類似した)表現に従っており、ニュートン法を開始するための平方根の非常に迅速な近似値を得ることができます。以下の手法は、浮動小数点形式(基数2)が基数2の対数を近似するという事実に基づいています。つまり、
log
2
(
m
×
2
p
)
=
p
+
log
2
(
m
)
{\displaystyle \log _{2}(m\times 2^{p})=p+\log _{2}(m)}
したがって、IEEE形式の32ビット単精度浮動小数点数(特に、表現された形式では累乗に127の バイアス が加えられている)の場合、そのバイナリ表現を32ビット整数として解釈し、それを でスケーリングし、127のバイアスを取り除くことで、
近似対数を得ることができます。つまり、
2
−
23
{\displaystyle 2^{-23}}
x
int
⋅
2
−
23
−
127
≈
log
2
(
x
)
.
{\displaystyle x_{\text{int}}\cdot 2^{-23}-127\approx \log _{2}(x).}
たとえば、1.0 は 16 進 数 0x3F800000 で表されますが、これを整数としてとると を表します。上記の式を使用すると 、 から予想されるとおり が得られます 。同様に、1.5 (0x3FC00000) から 0.5 が得られます。
1065353216
=
127
⋅
2
23
{\displaystyle 1065353216=127\cdot 2^{23}}
1065353216
⋅
2
−
23
−
127
=
0
{\displaystyle 1065353216\cdot 2^{-23}-127=0}
log
2
(
1.0
)
{\displaystyle \log _{2}(1.0)}
平方根を求めるには、対数を2で割って値を戻します。次のプログラムはこの考え方を示しています。指数の最下位ビットは意図的に仮数部に伝播します。このプログラムの手順を正当化する1つの方法は、 が 指数バイアスであり、 が 仮数部に明示的に格納されているビットの数であると仮定し、次のことを示すことです。
b
{\displaystyle b}
n
{\displaystyle n}
(
(
1
2
(
x
int
/
2
n
−
b
)
)
+
b
)
⋅
2
n
=
1
2
(
x
int
−
2
n
)
+
(
1
2
(
b
+
1
)
)
⋅
2
n
.
{\displaystyle \left(\left({\tfrac {1}{2}}\left(x_{\text{int}}/2^{n}-b\right)\right)+b\right)\cdot 2^{n}={\tfrac {1}{2}}\left(x_{\text{int}}-2^{n}\right)+\left({\tfrac {1}{2}}\left(b+1\right)\right)\cdot 2^{n}.}
/* float が IEEE 754 単精度浮動小数点形式であると想定します */
#include <stdint.h> float sqrt_approx ( float z ) { union { float f ; uint32_t i ; } val = { z }; /* ビット パターンを維持したまま型を変換します */ /* * 次のコードを正当化するには、次の式を証明してください * * ((((val.i / 2^m) - b) / 2) + b) * 2^m = ((val.i - 2^m) / 2) + ((b + 1) / 2) * 2^m) * * ただし * * b = 指数バイアス * m = 仮数ビット数 */ val . i -= 1 << 23 ; /* 2^m を減算します。 */ val . i >>= 1 ; /* 2 で割ります。 */ val . i += 1 << 29 ; /* ((b + 1) / 2) * 2^m を加算します。 */
return val . f ; /* 再び float として解釈します */ }
上記の関数の中核をなす3つの数学演算は、1行で表現できます。最大相対誤差を減らすために、追加の調整を加えることができます。したがって、キャストを除く3つの演算は、次のように書き直すことができます。
val.i = ( 1 << 29 ) + ( val.i >> 1 ) - ( 1 << 22 ) + a ;
ここで、 a は 近似誤差を調整するためのバイアスです。たとえば、 a = 0 の場合、結果は 2 の偶数乗 (例: 1.0) に対して正確ですが、他の数値の場合、結果はわずかに大きくなります (例: 2.0 の場合、1.414 ではなく 1.5 になり、誤差は 6% になります)。a = −0x4B0D2 の場合 、 最大相対誤差は ±3.5% に最小化されます。
近似値を方程式に対する ニュートン法 の初期推定値として使用する場合は 、次のセクションに示す逆数形式が適しています。
(
1
/
x
2
)
−
S
=
0
{\displaystyle (1/x^{2})-S=0}
平方根の逆数
上記ルーチンの変形が下記に含まれており、平方根の 逆数 を計算するために使用できます。つまり、 代わりに、Greg Walsh によって書かれました。整数シフト近似により、相対誤差は 4% 未満となり、 次の行で ニュートン法を 1 回反復すると、誤差はさらに 0.15% まで下がります。 コンピュータグラフィックスでは、これはベクトルを正規化する非常に効率的な方法です。
x
−
1
/
2
{\displaystyle x^{-1/2}}
float invSqrt ( float x ) { float xhalf = 0.5f * x ; union { float x ; int i ; } u ; u . x = x ; u . i = 0x5f375a86 - ( u . i >> 1 ); /* 次の行は、精度を上げるために任意の回数繰り返すことができます */ u . x = u . x * ( 1.5f - xhalf * u . x * u . x ); return u . x ; }
一部のVLSIハードウェアでは、2次多項式推定とそれに続くゴールドシュミット 反復法を使用して逆平方根を実装しています 。
負の平方または複素平方
S < 0の場合 、その主平方根は
S
=
|
S
|
i
.
{\displaystyle {\sqrt {S}}={\sqrt {\vert S\vert }}\,\,i\,.}
S = a + bi ( a と b は実数、 b ≠ 0)の場合 、その主平方根は
S
=
|
S
|
+
a
2
+
sgn
(
b
)
|
S
|
−
a
2
i
.
{\displaystyle {\sqrt {S}}={\sqrt {\frac {\vert S\vert +a}{2}}}\,+\,\operatorname {sgn}(b){\sqrt {\frac {\vert S\vert -a}{2}}}\,\,i\,.}
これはルートを二乗することで検証できる。
ここで
|
S
|
=
a
2
+
b
2
{\displaystyle \vert S\vert ={\sqrt {a^{2}+b^{2}}}}
はS の 法 です。 複素数 の主平方根は、 実部が負でない根として定義されます。
参照
注記
^ 係数 2 と 6 が使用されるのは、指定された桁数で可能な最小値と最大値の幾何平均を近似 する ため です 。
1
⋅
10
=
10
4
≈
1.78
{\displaystyle {\sqrt {{\sqrt {1}}\cdot {\sqrt {10}}}}={\sqrt[{4}]{10}}\approx 1.78\,}
10
⋅
100
=
1000
4
≈
5.62
{\displaystyle {\sqrt {{\sqrt {10}}\cdot {\sqrt {100}}}}={\sqrt[{4}]{1000}}\approx 5.62\,}
^ 四捨五入されていない推定値は、100で最大絶対誤差が2.65、y=1、10、100で最大相対誤差が26.5%である。
^ 数字がちょうど2つの平方の中間、例えば30.5の場合、大きい方の数字を推測します。この場合は6です。
ちなみにこれは、 y = 1における y = x 2 の接線の方程式です 。
参考文献
^ Goldschmidt, Robert E. (1964). Applications of Division by Convergence (PDF) (論文). M.Sc. dissertation. MIT OCLC 34136725. 2015-12-10 にオリジナルからアーカイブ (PDF)されました 。2015-09-15 に取得 。
^ 「著者」。IBM Journal of Research and Development。11 :125–127。1967年 。doi : 10.1147/rd.111.0125。2018年7月18日時点のオリジナルよりアーカイブ。
^ 参照: 一般化連分数#表記
^ 参照: 連分数#表記法
^ 参照: 周期連分数
文献
アブラモウィッツ、ミルトン、ステグン、アイリーン A. (1964)。 数式、グラフ、数学表付き数学関数ハンドブック 。クーリエ・ドーバー出版。p. 17。ISBN 978-0-486-61272-0 。
ベイリー、デイビッド、 ボルウェイン、ジョナサン (2012)。「古代インドの平方根: 法医学的古数学の演習」 (PDF) 。 アメリカ数学月刊誌 。第 119 巻、第 8 号。646 ~ 657 ページ。2017 年 9 月 14 日 閲覧 。
Campbell- Kelly , Martin (2009 年 9 月)。「コンピューティングの起源」。Scientific American。301 ( 3 ): 62–69。Bibcode :2009SciAm.301c..62C。doi : 10.1038 /scientificamerican0909-62。JSTOR 26001527。PMID 19708529 。
クック、ロジャー(2008)。 古典代数:その性質、起源、用途。ジョン ・ ワイリー・アンド・サンズ。p.59。ISBN 978-0-470-25952-8 。
ファウラー 、デイビッド、ロブソン、エレノア( 1998)。「古代バビロニア数学における平方根近似:YBC 7289 の文脈」 (PDF) 。Historia Mathematica。25 ( 4 ): 376。doi : 10.1006/hmat.1998.2209 。
Gower, John C. (1958). 「ルート抽出のための反復法に関するメモ」. コンピュータジャーナル . 1 (3): 142–143. doi : 10.1093/comjnl/1.3.142 .
ジャクソン、テレンス (2011-07-01)。「95.42 自然数の無理数平方根 — 幾何学的アプローチ」。The Mathematical Gazette。95 ( 533 ): 327–330。doi : 10.1017 /S0025557200003193。ISSN 0025-5572。S2CID 123995083 。
Guy, Martin; UKC (1985)。「Woo 氏のアバカス アルゴリズムによる高速整数平方根 (アーカイブ)」。2012 年 3 月 6 日にオリジナルからアーカイブ。
ヒース、トーマス (1921)。ギリシャ数学史第2巻。オックスフォード:クラレンドン・プレス。pp.323-324。
Lomont, Chris (2003)。「高速逆平方根」 (PDF) 。
Markstein, Peter (2004 年 11 月)。Goldschmidt アルゴリズムを使用したソフトウェア除算と平方根 (PDF) 。第 6 回 実数とコンピュータに関する会議。 ドイツ、 ダグストゥール。CiteSeerX 10.1.1.85.9648 。
Piñeiro, José-Alejandro; Díaz Bruguera, Javier (2002 年 12 月)。「逆数、除算、平方根、逆平方根の高速倍精度計算」 IEEE Transactions on Computers 51 ( 12): 1377–1388. doi :10.1109/TC.2002.1146704。
Sardina, Manny (2007)。「(折り畳まれた)連分数を使用して根を抽出する一般的な方法」。サリー (英国)。
Simply Curious (2018年6月5日)。「バクシャーリー写本に屈する」。Simply Curious ブログ。 2020年12月21日 閲覧 。
スタイナーソン、アーン。ダン、コービット。ヘンドリー、マシュー (2003)。 「整数平方根関数」。
Wilkes, MV ; Wheeler, DJ ; Gill, S. (1951) 。 電子デジタルコンピュータ用プログラムの作成。オックスフォード: Addison-Wesley。pp. 323–324。OCLC 475783493。
外部リンク
Weisstein、Eric W. 「平方根アルゴリズム」 。MathWorld 。
引き算による平方根
整数平方根アルゴリズム (Andrija Radović 著)
パーソナル計算機アルゴリズム I : 平方根 (ウィリアム E. エグバート)、ヒューレット・パッカード ジャーナル (1977 年 5 月) : 22 ページ
平方根を学ぶための計算機