平方根アルゴリズムは非負の平方根を計算します正の実数自然数の平方根は、完全平方数を除いてすべて無理数であるため、[ 1 ] 平方根は通常、有限の精度でしか計算できません。これらのアルゴリズムは通常、精度が徐々に高まる一連の近似値を構築します。
ほとんどの平方根計算方法は反復的です。反復的な改良は、何らかの終了条件が満たされるまで実行されます。改良方法の1つに、ニュートン法の特殊なケースであるヘロン法があります。除算が乗算よりもはるかにコストがかかる場合は、代わりに逆平方根を計算する方が望ましい場合があります。
平方根を計算するには、桁ごとに計算する方法やテイラー級数を用いる方法もあります。平方根の有理数近似は、連分数展開を用いて計算できます。
採用する手法は、必要な精度、利用可能なツール、および計算能力によって異なります。手法は、大まかに、暗算に適したもの、通常は少なくとも紙と鉛筆を必要とするもの、そしてデジタル電子計算機やその他の計算装置で実行されるプログラムとして実装されるものに分類できます。アルゴリズムは、収束性(指定された精度を達成するために必要な反復回数)、個々の演算(例えば除算)または反復の計算複雑度、および誤差伝播(最終結果の精度)を考慮に入れる場合があります。
紙と鉛筆を使った合成除法や級数展開法など、初期値を必要としない方法もあります。ただし、用途によっては整数平方根が必要となる場合があり、その場合は平方根を最も近い整数に丸めるか切り捨てる必要があります(この場合、修正された手順が用いられることもあります)。
平方根(特に2の平方根)を求める手順は、少なくとも紀元前17世紀の古代バビロニア時代から知られていました。 バビロニアの数学者は2の平方根を1の後の3桁の60進数で計算しましたが、その正確な方法は分かっていません。彼らは斜辺を近似する方法を知っていました。 (例えば)高さが幅が棒)そして、彼らは近似値を見つけるために同様のアプローチを使用した可能性がある。[ 2 ]
1世紀のエジプトのヘロンの方法は、平方根を計算するための最初の確実なアルゴリズムであった。[ 3 ]
現代の分析手法は、ルネサンス初期に西ヨーロッパにアラビア数字体系が導入された後に発展し始めた。 [ 4 ]
今日では、ほぼすべてのコンピューティングデバイスに、プログラミング言語の構成要素、コンパイラの組み込み関数またはライブラリ関数、あるいは前述の手順のいずれかに基づくハードウェア演算子として、高速かつ正確な平方根関数が備わっています。
多くの反復平方根アルゴリズムでは、初期シード値が必要です。シードはゼロ以外の正の数でなければなりません。1から100までの範囲である必要があります。、平方根を求める数。平方根はその範囲内にある必要があるため。シードが根から遠い場合、アルゴリズムはより多くの反復を必要とします。(または)、するとおよそ根の桁数を把握するだけでも、反復計算が無駄になります。そのため、精度は限られるものの計算が容易な概算値を用意しておくと便利です。一般的に、初期推定値が正確であればあるほど、収束は速くなります。ニュートン法の場合、根よりやや大きいシード値を用いると、根よりやや小さいシード値を用いるよりも、収束がわずかに速くなります。
一般的に、推定値は根を含むことがわかっている任意の区間(例えば、)推定値は、関数近似の特定の値です。区間内で。より良い推定値を得るには、区間の境界をより厳密にするか、または、より適切な関数近似を見つける必要があります。後者は通常、近似に高次の多項式を使用することを意味しますが、すべての近似が多項式であるとは限りません。一般的な推定方法には、スカラー、線形、双曲線、対数などがあります。通常、10進数は暗算または紙と鉛筆による推定に使用されます。2進数はコンピュータによる推定に適しています。推定では、数値が科学的記数法で表されるように、指数と仮数は通常別々に扱われます。
通常、その数は科学的記数法では次のように表されます。どこnは整数であり、可能な平方根の範囲はどこ。
スカラー法では範囲を区間に分割し、各区間の推定値は単一のスカラー値で表されます。範囲を単一の区間とみなす場合、算術平均 (5.5) または幾何平均 ()回これらは妥当な推定値です。これらの絶対誤差と相対誤差は異なります。一般的に、単一のスカラー値は非常に不正確です。より精度の高い推定では、範囲を2つ以上の区間に分割しますが、スカラー値による推定は本質的に精度が低いという欠点があります。
2 つの区間を幾何級数的に分割した場合、平方根以下のように推定できる[注1 ]
この推定値の最大絶対誤差はで最大相対誤差は100%で。
のために因数分解すると推定値は。
絶対誤差は246、相対誤差はほぼ70%である。
より正確な推定値、そして標準的な方法は、関数の線形近似である。小さな弧に沿って。上記のように、数Sから底のべき乗が因数分解され、区間が[ 1, 100 ]に縮小された場合、弧をまたぐ割線、または弧上のどこかの接線を近似として使用できますが、弧と交差する最小二乗回帰直線の方がより正確です。
最小二乗回帰直線は、推定値と関数の値の平均差を最小化します。その方程式は次のとおりです。並べ替え、計算を容易にするために係数を丸めると、
これは、関数の単一部分線形近似で達成できる平均的に最良の推定値です。区間[ 1, 100 ]において、 a =100で最大絶対誤差1.2 、S =1および10で最大相対誤差30%となる。 [注2 ]
10 で割るには、 aの指数から 1 を引くか、比喩的に言えば小数点を 1 桁左に移動させます。この定式化では、任意の加算定数 1 に小さな増分を加えることで満足のいく推定値が得られるため、正確な数値を覚えておく必要はありません。範囲[ 1, 100 ]にわたる 1 つの線を使用した近似値 (丸められたかどうかにかかわらず)は、有効数字 1 桁未満の精度です。相対誤差は 1/2 2より大きいため、2 ビット未満の情報しか提供されません。範囲が 2 桁もあるため、この種の推定としてはかなり大きく、精度が著しく制限されます。
区分的線形近似を用いると、はるかに良い推定値が得られます。これは、元の弧のいくつかのサブアークをそれぞれ近似する複数の線分です。使用する線分の数が多いほど、近似精度は高くなります。最も一般的な方法は接線を使用することです。重要なのは、弧をどのように分割するか、接点をどこに配置するかです。y = 1からy = 100までの弧を分割する効果的な方法は、幾何学的に分割することです。2 つの区間の場合、区間の境界は元の区間の境界の平方根、1×100 です。つまり、[ 1, 2√100 ]と[ 2√100 , 100 ]です。 3つの区間の場合、境界は100の立方根です。[1, 3√100 ]、[ 3√100 , ( 3√100 ) 2 ]、[( 3√100 ) 2 , 100]など。2つの区間の場合、2√100 = 10となり、非常に便利な数です。接線は簡単に導出でき、次の位置にあります。そしてそれらの式は次のとおりです。 そして逆数を取ると、平方根は次のようになります。そしてしたがって、:
最大絶対誤差は区間の上限値であるa = 10 と 100 で発生し、それぞれ 0.54 と 1.7 です。最大相対誤差は区間の端点であるa = 1、10、100 で発生し、いずれの場合も 17% です。17% または 0.17 は 1/10 より大きいため、この方法では小数点以下の精度しか得られません。
双曲線近似は、場合によっては有効です。双曲線も凸曲線であり、直線よりもy = x 2の弧に沿っていることが多いためです。双曲線近似は、浮動小数点除算が必須となるため、計算がより複雑になります。区間[ 1, 100 ]におけるx 2のほぼ最適な双曲線近似は、次のようになります。移項すると、平方根はしたがって、:
全体の推定値の精度が1桁の小数点以下までで十分であり、暗算で計算できます。この双曲線推定値は、平均的にはスカラー推定値や線形推定値よりも優れています。絶対誤差の最大値はa = 100で 1.58 、相対誤差の最大値はa = 10で、推定値 3.67 は平方根 3.16 より 16.0% 高くなっています。代わりに推定値 10 からニュートン・ラフソン法を反復計算すると、双曲線推定値と一致する 3.66 に到達するには 2 回の反復計算が必要になります。75 のようなより一般的なケースでは、双曲線推定値 8.00 は 7.6% 低いだけであり、より正確な結果を得るには 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 で割ったべき乗を掛けることなので、、
この方法は、最良の最初の桁に丸めるため、暗黙のうちに有効数字1桁の精度が得られます。
この方法は、オペランドを囲む最も近い正方形の間を補間することで、ほとんどの場合、有効数字3桁まで拡張できます。、 それからは、おおよそ k に分数を加えた値、つまりaとk の差を 2つの平方数の差で割った値に相当します。
どこ
最後の演算は、上記と同様に、結果に10のべき乗を2で割った値を掛けることです。
kは10進数、Rは10進数に変換する必要のある分数です。通常、分子は1桁、分母は1桁または2桁なので、暗算で10進数に変換できます。
75の平方根を求めなさい。
なので、 aは 75、 nは 0 です。乗算表から、仮数の平方根は 8 点何桁でなければなりません。なぜなら、 aは 8 × 8 = 64 と 9 × 9 = 81 の間にあるため、 kは 8 です。何桁かはRの小数表現です。分数Rでは、分子は75 − k 2 = 11、分母は81 − k 2 = 2 k + 1 = 17です。11/17 は 12/18 = 2/3 = 0.67 より少し小さいので、0.66 と推測します (ここでは推測しても構いません。誤差は非常に小さいです)。最終的な推定値は8 + 0.66 = 8.66です。
√75を有効数字3桁で表すと8.66となるので、この推定値は有効数字3桁まで正確です。この方法を用いたすべての推定値がこれほど正確になるわけではありませんが、近い値が得られます。
(コンピュータが内部的に行っているように)バイナリ数体系で作業する場合、 Sを次のように表現します。どこ平方根推定値として
これは、有効数字3桁の係数を持つ最小二乗回帰直線です。最大絶対誤差は0.0408です。最大相対誤差は3.0%で、計算上都合の良い丸め推定値(係数が2のべき乗であるため)は次のとおりです。
これは、2 で最大絶対誤差が 0.086、a = 0.5およびa = 2.0で最大相対誤差が 6.1% である。
のために二値近似ではしたがって、推定値の絶対誤差は19、相対誤差は5.3%です。相対誤差は1/2 4よりわずかに小さいので、推定値は4ビット以上まで正確です。
8 ビットの精度での推定値は、の上位 8 ビットのテーブルを参照することで取得できます。ただし、ほとんどの浮動小数点表現では上位ビットが暗黙的に含まれており、8 ビットの下位ビットは丸められることに注意してください。テーブルは、事前に計算された 8 ビットの平方根値の 256 バイトです。たとえば、1.8515625 10を表すインデックス 11101101 2の場合、エントリは1.359375 10を表し、1.8515625 10の8 ビット精度 (2 桁以上の小数点以下)での平方根です。
近似のための最初の明示的なアルゴリズムこの方法は、紀元60年に著した『メトリカ』の中でこの方法を記述した1世紀のギリシャの数学者、アレクサンドリアのヘロンにちなんで、ヘロンの方法として知られています。[ 3 ]この方法はバビロニアの方法とも呼ばれますが(斜辺を近似するためのバビロニアの方法とは混同しないでください)、この方法がバビロニア人に知られていたという証拠はありません。
正の実数が与えられた場合x 0 > 0を任意の正の初期推定値とする。ヘロン法は反復計算から成り、 所望の精度が達成されるまで。この方程式で定義されるものは、
これはニュートン法を用いて解くことと同等である。このアルゴリズムは二次収束します。反復ごとにほぼ倍増する。[ 5 ]
基本的な考え方は、正の実数の平方根に対する過大評価であるそれからは過小評価となり、その逆もまた然りであるため、これら2つの数値の平均は、より良い近似値を提供すると合理的に期待できる。(この主張の正式な証明は、算術平均と幾何平均の不等式に基づいている。この不等式は、この平均が常に平方根の過大評価となることを示しており、平方根に関する記事で述べられているように、収束を保証する。)
より正確には、は、そして推定誤差は、すると、二項式は次のように展開できます。 そして誤差項を解く
したがって、誤差を補正して古い推定値を更新することができます。 計算された誤差は正確ではなかったため、これは実際の答えではなく、次の修正ラウンドで使用する新たな推定値となります。更新プロセスは、必要な精度が得られるまで繰り返されます。
このアルゴリズムはp進数でも同様に機能しますが、実数の平方根とp進数の平方根を同一視するために使用することはできません。たとえば、この方法によって、実数では+3に収束するが2進数では-3に収束する有理数列を構築できます。
decimalからDecimal 、localcontext 、getcontextをインポートします数値タイプ= int | float | Decimaldef sqrt_Heron (s :数値型、精度: int | None = None 、推測:数値型|なし=なし) ->小数:""" ヘロン・ニュートン法を用いて、任意精度で平方根(s)を計算します。 :param s: 平方根を計算する非負の数。 :param precision: 有効桁数。 デフォルトでは現在の10進数コンテキストが適用されます。 最小サポート精度は2です。 (丸め誤差を避けるため、精度=1は許可されていません。) :param guess: 初期推定値。デフォルトは s / 2 です。 :return: 指定された精度に丸められた平方根の近似値。 """s == 0 の場合:return Decimal ( 0 )s = Decimal ( s )s < 0 の場合:raise ValueError ( "sqrt(s) は負の数に対して定義されていません。" )精度がNoneの場合:precision = getcontext () . prec # 指定されていない場合は現在のグローバルコンテキストを使用する# 最小精度を静かに強制する精度が2未満の場合:精度= 2推測がNoneの場合:guess = Decimal ( s / 2 )ガード= 25 # 内部安定性のための一時的な追加桁max_iter = 10_000# ローカルコンテキスト: 精度変化を分離するwith localcontext () as ctx :ctx.prec = precision + guard推測値= (推測値+ s /推測値) / 2for _ in range ( max_iter ):next_guess = ( guess + s / guess ) / 2# 改善が十分に小さかったら止めるif guess - next_guess < Decimal ( f "1e- { precision } " ):壊すguess = next_guessそれ以外:raise ArithmeticError ( f "Heron メソッドは{ max_iter }回以内の反復で収束しませんでした" )# 目標精度に丸める(ガードを取り除く)ctx.prec =精度return + next_guesssqrt_Heron以下の例は、さまざまな入力値を用いた関数の実行を示しています。
print ( f "1) { sqrt_Heron ( 125348 , precision = 7 , guess = 600 ) } " ) print ( f "2) { sqrt_Heron ( Decimal ( '3.1415926535897932384626433832795028841971693993' )) } " ) print ( f "3) { sqrt_Heron ( 2 , 1_000_157 ) } " ) print ( f "4) { sqrt_Heron ( 2 , 10_000_005 , 1.414 ) } " ) print ( f "5) { sqrt_Heron ( 2 , 100_000_000 , 1 ) } " )これにより、以下の出力が得られます。
1) 354.0452 2) 1.772453850905516027298167483 3) 1.4142135623730950488016887242 ... 269732025731849141493880004856742892 4) 1.4142135623730950488016887242 ... ... 872480508054123572727872131589714262 5) 1.4142135623730950488016887242 ... ... ... 023678977744844723443287604232894971
広告1)
計算のために7桁の有効数字に到達するには、次の手順を踏む必要があります。
したがって有効数字7桁(四捨五入)。
2)計算(6回の反復ステップ)デフォルトの精度に。[注5 ]
3)計算(22回の反復ステップ)1,000,157桁まで。[ 6 ]
Ad 4)計算(23回の反復ステップ)10,000,005桁まで。[ 7 ]
5)計算(28回の反復ステップ)1億桁まで。
妥当な初期推定値であれば、多くの反復計算は必要ないようである。
ヘロンの方法には以下の特性がある。
簡単に言うと:反復処理で次の値を超えると(これはすぐに起こります)または、1 ステップ後に)以降のすべての推定値は、しかし、毎回小さくなるので、数列は「下へ滑り落ちて」そして収束する。
プログラムの41行目で、guess値が設定されます。コードの46行目では、負の値にはなり得ない。
連続する推定値の差を利用することで、
停止基準として、この方法は近似のシーケンスを保証します。真の値に収束している連続する差分が十分に小さくなれば、目標は達成される。重要な洞察は、絶対誤差が
連続的な改善の規模に直接関係する具体的には、線形または二次的に収束する反復法には定数が存在する。そのため
この関係は、絶対誤差は減少する。も小さくなる。したがって、反復を停止すると所定のしきい値を下回ると、実際のエラーが最大でもそのしきい値内に収まることが保証されます。

仮にすると任意の自然数に対して相対誤差を定義される そしてこうして
すると、次のことが示される。
そしてこうして したがって、収束は保証され、二次関数的である。
上記の概算値をバビロニア方式で使用した場合、精度が低い順に以下のようになります。 ;&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桁多く残しておくことをお勧めします。大きな丸め誤差を避けるために計算されます。
上記のプログラムでは、見積もり(強調表示された41行目と43行目)が表示されます。
推測値= (推測値+ s /推測値) / 2# ...next_guess = ( guess + s / guess ) / 2に置き換えられる
guess *= ( guess * guess + 3 * s ) / ( 3 * guess * guess + s )# ...next_guess = guess * ( guess * guess + 3 * s ) / ( 3 * guess * guess + s )この関数は、ハレー法のsqrt_Heron実装に変換され、
ハレーの方法と同様に、推定値は必ずしも一方向に動くとは限らないため、46行目は次のようになります。
if abs ( guess - next_guess ) < Decimal ( f "1e- { precision } " ):ハレー法は反復ごとに収束が速く、根への収束率は3次で2次よりも優れていますが、1回の反復で5回の乗算(除算を3回の乗算として数える)が必要です。5つの例題の計算は、それぞれ4回、4回、14回、15回、19回の反復ステップで完了します。一方、ヘロン法は除算が1回(乗算3回)しか必要ないため、長期的にはヘロン法の方がわずかに優れています。
平方根の近似値を求めるこの方法は、バクシャリ写本と呼ばれる古代インドの写本に記述されています。これはヘロン法の2回の反復と代数的に等価であり、したがって4次収束します。つまり、近似値の正しい桁数は反復ごとにほぼ4倍になります。[ 8 ]現代の記法を用いた元の記述は次のとおりです。、 させて初期近似値続いて、以下のように繰り返します。
値そしてこれらはヘロン法で計算されたものと全く同じです。これを確認するには、ヘロン法の2番目のステップで計算します。 そして、定義を使うことができますそして分子を次のように並べ替える:
これは、整数から始めて平方根の有理近似を構築するために使用できます。は整数として選ばれます。に近い、 そして絶対値が最小となる差が である場合、最初の反復は次のように記述できます。
バクシャリ法は、分数根を含む任意の根の計算に一般化できる。[ 9 ]
バクシャリ法の後半部分は、ヘロンの反復法のより単純な形式として繰り返し使用できると考える人もいるかもしれない。 しかし、これは数値的に不安定です。元の入力値を参照せずに精度は元の計算の精度によって制限される。そしてそれはすぐに不十分になる。
同じ例を使ってヘロン法の例と同様に、最初の反復では
同様に、2回目の反復では ヘロンの方法とは異なり、は8桁まで計算する必要があります。なぜなら、のエラーを修正しません。
この手法は、1600 年頃に出版されたFrançois Vièteの研究に由来し[ 10 ] 、二項定理に基づいており、本質的には逆アルゴリズムを解くものである。バビロニア方式よりは遅いが、いくつかの利点がある。
デメリットは以下のとおりです。
ネイピアの骨には、このアルゴリズムの実行を支援する機能が含まれている。シフトn乗根アルゴリズムは、この方法を一般化したものである。
まず、数Sの平方根を求める場合を考えてみましょう。これは、10進数2桁XYの平方根です。ここで、Xは十の位、Yは一の位です。具体的には次のようになります。 Sは3桁または4桁の小数点で構成されます。
桁ごとのアルゴリズムを開始するには、Sの桁を右から 2 桁ずつの 2 つのグループに分割します。つまり、最初のグループは 1 桁または 2 桁になります。次に、X 2が最初のグループ以下となる 最大の桁をXの値として決定します。次に、最初のグループとX 2の差を計算し、2 番目のグループをそれに連結して 2 番目の反復を開始します。これは、減算に相当します。Sから、そして残るのはS'を10で割り、次に2Xで割り、整数部分を残してYを推測します。2Xと暫定的なYを連結し、 Yを掛けます。推測が正しければ、これは次の計算と同等です。したがって、余り、つまりS'と結果の差はゼロになります。結果がS'より大きい場合は、推測値を1下げて、余りが0になるまで再度試します。これは答えが完全平方根XYである単純なケースなので、アルゴリズムはここで停止します。
同じ考え方を、次に任意の平方根の計算に拡張できます。S をn個の正の数 の和として表すことで、Sの平方根を見つけることができると仮定します。
基本同一性を繰り返し適用することによって 右辺の項は次のように展開できます。
この式を使うと、次の値を順に推測することで平方根を求めることができます。s. 数字がが既に推測されている場合、上記の総和の右辺のm番目の項は次のように与えられます。どここれはこれまでに見つかったおおよその平方根です。再帰を満たす必要がある どこは、すなわち、残りの部分、すべての人々のために初期化付きいつ正確な平方根が見つかった場合、そうでない場合は、s は平方根の適切な近似値を与え、は近似誤差である。
例えば、十進数システムでは どこはプレースホルダーであり、係数です。平方根計算の任意の m 番目の段階では、これまでに見つかった近似根は、そして総和項は次のように与えられる。
ここでは位取りがが10の偶数乗である場合、余りの最上位2桁のみを扱えばよい。その最初の項は任意のm番目の段階において。以下のセクションではこの手順を体系化します。
10進数以外の数体系でも平方根を計算するのに同様の方法が使えることは明らかです。例えば、2進数体系で桁ごとの平方根を求めるのは非常に効率的です。なぜなら、は、より小さなバイナリ数字のセット {0,1} から検索されます。これにより、各段階での値がどちらかのためにまたはのために私たちには2つの選択肢しかないという事実また、価値を決定するプロセスもm番目の計算段階では、より簡単になります。これは、次のことを確認するだけでよいからです。のためにこの条件が満たされる場合、; そうでない場合はまた、2倍の演算が左ビットシフトによって行われるという事実も、計算を有利にする。
元の数を10進数で書きます。数字の書き方は筆算のアルゴリズムに似ており、筆算と同様に、平方根は上の行に書きます。次に、小数点から始めて左右に桁を2桁ずつに分けます。平方根の小数点は、平方数の小数点の上にきます。平方根の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 つの用語万が一ゼロ以外、別々の変数、:
そして各ステップで効率的に更新できます。
ご了承ください: これは、以下の関数で返される最終結果です。
Pythonプログラムは計算しますこのアルゴリズムは、整数平方根を桁ごと(ビットごと)に計算する方法です。[ 11 ]
def isqrt ( x : int ) -> int : assert x >= 0 , "sqrt の入力は負の値であってはなりません"op : int = x # X_(n+1) res : int = 0 # c_n# d_n は、4 の最大のべき乗 <= n から始まります。one : int = 1 while one <= op : one <<= 2 # 'one' は、4 の最大のべき乗 <= x です。one >>= 2# dₙ … d₀ の間、one != 0 の間: op >= res + one の場合: # X_(m+1) ≥ Y_m の場合、a_m = 2^m op -= res + one # X_m = X_(m+1) - Y_m res += 2 * one # c_m = c_m + 2*d_m res //= 2 # c_(m-1) = c_m / 2 one //= 4 # d_(m-1) = d_m / 4# c_(-1)はresを返しますバイナリ、10進数、またはその他の基数でのより高速なアルゴリズムは、ルックアップテーブルを使用することで実現できます。これは、より多くの記憶領域を犠牲にして実行時間を短縮することになります。[ 12 ]
ポケット電卓は通常、指数関数と自然対数を計算する優れたルーチンを実装し、対数の性質を使用して見つけた恒等式を使用してSの平方根を計算します()と指数関数() : 分数の分母はn乗根に対応します。上記の例では分母は2なので、この式は平方根を求めることを示しています。対数表や計算尺を使って平方根を計算する際にも、同じ公式が用いられます。
この方法は、平方根を求めるのに適用できます。そして、最もよく収束するのはしかし、これはコンピュータベースの計算にとって実際には制限ではありません。なぜなら、2 進浮動小数点表現と固定小数点表現では、乗算は自明だからです。4の整数乗によって、したがってそれぞれ、対応する2のべき乗、指数の変更、またはシフトによって。したがって、範囲に移動できますさらに、この方法は一般的な除算ではなく、加算、減算、乗算、および2のべき乗による除算のみを使用するため、実装は非常に簡単です。この方法の欠点は、バビロニア式のような単一変数反復法とは異なり、数値誤差が蓄積されることです。
このメソッドの初期化ステップは 反復手順は次のとおりである。 それから、(その間)
収束したがって、は二次関数です。
この方法の証明は比較的簡単です。まず、反復定義を書き直します。として 帰納法によって証明するのは簡単である。 したがって収束望ましい結果へ収束によって保証される0 に、これは次のことから導かれる。
この方法は、初期の電子計算機の1つであるEDSACで使用するために、1950年頃にMV Wilkes、DJ Wheeler、S. Gillによって開発されました[ 13 ] 。 [ 14 ]この方法は後に一般化され、平方根以外の根の計算も可能になりました[ 15 ]。
以下は、 Sの逆平方根を求める反復法です。見つかったら、単純な掛け算によって:これらの反復計算は乗算のみで除算は行わないため、バビロニア法よりも高速です。ただし、安定性に欠けます。初期値が逆平方根に近くない場合、反復計算の結果は逆平方根に収束するのではなく、むしろそこから乖離していきます。そのため、これらの方法を適用する前に、概算値に対してバビロニア法を一度実行しておくことが有効な場合があります。
Goldschmidt's algorithm is an extension of Goldschmidt division, named after Robert Elliot Goldschmidt,[16][17] which can be used to calculate square roots. Some computers use Goldschmidt's algorithm to simultaneously calculate and . Goldschmidt's algorithm finds faster than Newton-Raphson iteration on a computer with a fused multiply–add instruction and either a pipelined floating-point unit or two independent floating-point units.[18]
The first way of writing Goldschmidt's algorithm begins
and iterates until is sufficiently close to 1, or a fixed number of iterations. The iterations converge to and Note that it is possible to omit either and from the computation, and if both are desired then may be used at the end rather than computing it through in each iteration.
A second form, using fused multiply-add operations, begins
and iterates until is sufficiently close to 0, or a fixed number of iterations. This converges to and
If N is an approximation to , a better approximation can be found by using the Taylor series of the square root function:
As an iterative method, the order of convergence is equal to the number of terms used. With two terms, it is identical to the Babylonian method. With three terms, each iteration takes almost as many operations as the Bakhshali approximation, but converges more slowly. Therefore, this is not a particularly efficient way of calculation. To maximize the rate of convergence, choose N so that is as small as possible.
The continued fraction representation of a real number can be used instead of its decimal or binary expansion and this representation has the property that the square root of any rational number (which is not already a perfect square) has a periodic, repeating expansion, similar to how rational numbers have repeating expansions in the decimal notation system.
Quadratic irrationals (numbers of the form (ここでa、b、cは整数)特に整数の平方根は、周期的な連分数展開を持ちます。平方根の数値ではなく、その連分数展開、ひいてはその有理数近似を求めることが求められる場合もあります。平方根を求める正の数をSとします。初期推定値としてa を、剰余項をrとすると、次のように書くことができます。なぜなら私たちはSの平方根は次のように 表すことができます。
この式を適用することで分数の分母項については、次のようになります。
簡潔な表記法—連分数の分子/分母展開(上記)は、記述するのもテキストフォーマットシステムに埋め込むのも面倒です。そのため、数学者たちは次のよう ないくつかの代替表記法を考案しました。
いつ全体を通して、さらに簡潔な表記法は次のとおりです。[注7 ] 循環分数(完全平方数でない平方根はすべて循環分数である)の場合、循環項は一度だけ表され、上線は上線が引かれた部分の無限の繰り返しを示す。[注8 ]
√2の場合、 aの値は1なので、その表現は次のようになります。
この方法で進めると、平方根の 一般化された連分数は次のようになります。
このような分数[ 19 ]を評価して根を求める最初のステップは、目的の数の根と選択した分母の数に対して数値代入を行うことです。たとえば、標準形ではr = 1であり、 √2の場合、a = 1なので、3つの分母の数値連分数は次のようになります。
ステップ2は、連分数を下から順に、分母を1つずつ減らしていき、分子と分母が整数となる有理分数を得ることです。簡約は次のように行います(最初の3つの分母を取ります)。
最後に(ステップ3)、有理分数の分子を分母で割って、平方根の近似値を求めます。 小数点以下3桁に丸めます。
√2の実際の値は、有効数字 3 桁で 1.41 です。相対誤差は 0.17% なので、有理分数はほぼ 3 桁の精度で良好です。分母を増やすと、近似値は順次向上します。分母が 4 の場合、分数は次のようになります。、ほぼ4桁の精度まで良好、など。
以下は、平方根、その単純な連分数、および分母が99までの初項(収束項 と呼ばれる)の例です。
一般的に、有理分数の分母が大きいほど、近似精度は高くなります。また、連分数を切り捨てると、その分母以下の分数の平方根に最もよく近似する有理分数が得られることも示せます。例えば、分母が70以下の分数で、 99/70ほど√2によく近似する分数は存在しません。
数値は浮動小数点形式で次のように表されます。これは科学的記数法とも呼ばれます。その平方根は立方根や対数にも同様の公式が適用される。一見すると、これは簡便性の向上にはならないが、近似値のみが必要な場合は、次のようになる。桁違いに良い。次に、いくつかのべき乗pは奇数になることを認識してください。したがって、3141.59 = 3.14159 × 103底の分数べき乗を扱うのではなく、仮数を底で乗算し、べき乗から 1 を引いて偶数にします。調整された表現は 31.4159 × 10に相当します。2平方根は√ 31.4159 × 10になります1 .
調整された仮数の整数部分を取ると、1 から 99 までの値しか存在せず、それを 99 個の事前に計算された平方根の表へのインデックスとして使用して推定を完了できます。16 進数を使用するコンピュータではより大きな表が必要になりますが、2 進数を使用するコンピュータでは 3 つのエントリだけで済みます。調整された仮数の整数部分の可能なビットは 01 (べき乗が偶数なのでシフトは行われず、正規化された浮動小数点数は常にゼロ以外の上位桁を持つことを思い出す) または、べき乗が奇数の場合は 10 または 11 で、これらは元の仮数の最初の2ビットです。したがって、6.25 = 110.01 はバイナリで 1.1001 × 2に正規化され、偶数乗となるため、仮数のペアとなるビットは 01 になります。一方、.625 = 0.101 はバイナリで 1.01 × 2 −1 に正規化され、奇数乗となるため、調整後の値は 10.1 × 2 −2となり、ペアとなるビットは 10 になります。 べき乗の最下位ビットが、ペアとなる仮数の上位ビットに反映されていることに注意してください。偶数乗の場合、最下位ビットはゼロで、調整後の仮数は 0 で始まりますが、奇数乗の場合はそのビットは 1 で、調整後の仮数は 1 で始まります。したがって、べき乗が半分になると、最下位ビットがシフトアウトされてペアとなる仮数の最初のビットになるのと同じです。
エントリが 3 つしかないテーブルは、仮数の追加ビットを組み込むことで拡張できます。しかし、コンピュータでは、テーブルへの補間を計算するよりも、同等の結果が得られるより単純な計算を見つける方が良い場合が多いです。今やすべては、表現形式の正確な詳細と、数値の各部分にアクセスして操作するために利用できる操作に依存します。たとえば、Fortran にはべき乗を取得する関数がありますEXPONENT(x)。良い初期近似を考案するために費やした労力は、それによって、悪い近似に必要な改良プロセスの追加の反復を回避することで回収されます。これらは少ないため (1 つの反復には除算、加算、および半分化が必要です)、制約は厳しいです。
多くのコンピュータはIEEE(またはそれに十分類似した)表現に従っており、ニュートン法を開始するための平方根の非常に高速な近似値を得ることができます。以下の手法は、浮動小数点形式(底2)が底2の対数を近似するという事実に基づいています。つまり、
したがって、IEEE形式の32ビット単精度浮動小数点数(特に、表現形式には127のバイアスが加算されている)の場合、そのバイナリ表現を32ビット整数として解釈し、それをスケーリングすることで近似対数を取得できます。127のバイアスを取り除くと、
例えば、1.0 は16 進数0x3F800000で表され、整数として扱うと、上記の式を使用すると、予想通り同様に、1.5 ( 0x3FC00000 ) から 0.5 が得られます。

平方根を求めるには、対数を 2 で割って値を元に戻します。次のプログラムはその考え方を示しています。指数部の最下位ビットは、意図的に仮数部に伝播するように設定されています。このプログラムの手順を正当化する 1 つの方法は、bを指数バイアス、n を仮数部に明示的に格納されているビット数と仮定し、次に、
/* float は IEEE 754 単精度浮動小数点形式であると仮定します */ #include <stdint.h>union FloatUInt { float f ; uint32_t i ; }float sqrtApprox ( float z ) { union FloatUInt 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 ; }上記の関数の中核を成す3つの数学演算は、1行で表現できます。最大相対誤差を減らすために、追加の調整を加えることができます。したがって、キャストを含まない3つの演算は、次のように書き換えることができます。
val.i = ( 1 << 29 ) + ( val.i >> 1 ) - ( 1 << 22 ) + a ;ここで、 aは近似誤差を調整するためのバイアスです。たとえば、a = 0 の場合、結果は 2 の偶数乗 (たとえば 1.0) に対して正確ですが、他の数値では結果がわずかに大きくなります (たとえば、2.0 に対して 1.5 となり、1.414... ではなく 6% の誤差になります)。a = − 0x4B0D2の場合、最大相対誤差は ±3.5% に最小化されます。a = 0 の場合、近似値は任意のvalの値に対してvalの平方根以上になります。
近似値をニュートン法の初期推定値として使用する場合、その場合は、次のセクションに示す逆形式が好ましい。
近似は、 a 、1 << 29、および -1 << 22の加算を単一の演算に組み合わせることでさらに最適化できます。これにより、(val.i >> 1) + 0x1FBB4F2Ea = − 0x4B0D2の場合は誤差訂正が最小になり、a = 0の場合は となります。(val.i >> 1) + 1FC00000
上記ルーチンの変形版を以下に示します。これは平方根の逆数を計算するために使用できます。代わりに、グレッグ・ウォルシュによって書かれた。整数シフト近似では相対誤差が4%未満となり、次の行でニュートン法を1回反復すると誤差はさらに0.15%まで低下した。 [ 20 ]コンピュータグラフィックスでは、ベクトルを正規化する非常に効率的な方法である。
union FloatInt { float x ; int i ; };float inv_sqrt ( float x ) { float xhalf = 0.5f * x ; union FloatInt 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次多項式の推定とそれに続くゴールドシュミット反復法を使用して逆平方根を実装しています。[ 21 ]
S < 0の場合 、その主平方根は
S = a + bi ( aとbは実数でb ≠ 0)の場合、その主平方根は