起因
昨日グループ内で、小規模パートナーがバイト バックエンドに関するインタビューの質問を送信しました。質問の内容は2 \sqrt{2}を求めるものです2小数点以下 10,000 桁について、直感的に考えてインターネットで情報を検索すると、解決策は大きく次の 3 つになります。多くの言語では小数点以下の精度が 10 (-10000) のレベルに達しないため、この質問を小数点以下 6 桁に単純化しましょう。
方法 1、直感的な二分法
指定された数値がnであると仮定すると、左側の境界を 0 に、右側の境界を n に設定し、mid = (0 + n) / 2 をとります。mid 2 が n より小さい場合は、左側の境界を Mid に設定し、それ以外の場合は、境界を Mid に設定します。サイクルを終了する条件は、左側と右側の境界の差が精度のしきい値 (右 -左< しきい値) 未満であることです。簡単なコードは次のとおりです。
double getSqrt(int n, double threshold)
double left = 0, right = n;
while ( right - left > threshold){
double mid = (left + right) / 2;
if (mid * mid == n) return mid;
else if (mid * mid < n) left = mid;
else right = mid;
}
return left;
ロジックは比較的単純なので、あまりコメントしません
方法 2、ニュートン反復法
ニュートン反復法は、理論的にはほとんどの多項式の根を見つけることができます (最小要件は関数が 2 次導出可能であることですが、これはこの記事の範囲ではないため省略します)。一般的な考え方は次のとおりです。曲線方程式 f(x) が与えられた場合、方程式の根は xn である必要があります
。バツんその場所で接線を作成し、xn + 1 x_{n+1}を見つけます。バツn + 1ここで、xn x_nバツん反復処理における確実な解です 初期解は任意に設定できますが、できるだけ正確である方が良いですxn x_n は
導出により求めるのが簡単ですバツん接線の方程式はffですf (xn x_nバツん) + f'f'f' (xn x_nバツん)( xxx -xn x_nバツん)、
簡略化は次のように計算できます。xn + 1 = xn − f ( xn ) f ' ( xn ) {x_{n+1} = x_n - \frac {f(x_n)} {f'(x_n)}}バツn + 1=バツん−f' (xん)f ( xん)
その後、このプロセスを継続的に繰り返すことができ、終了条件はxn − xn + 1 < しきい値 {x_n} - {x_{n+1}} < しきい値になります。バツん−バツn + 1<th r e s h o l d
この質問では、 f ( x ) = x 2 − nf(x) = x^2 - nf ( x )=バツ2−n、対応するf ' ( x ) = 2 x f'(x) = 2xf( × )_=2 xなので、コードは次のようになります
double getSqrtNt(double n, double threshold){
doulbe x_n1 = n / 2; //起始点设置, 这是我随便写的一个, 可以有更好的方法
double x_n = n;
while (abs(x_n1 - x_n) > threshold){
x_n = x_n1;
x_n1 = xn - (xn * xn - n)/(2 * xn)
}
return xn;
}
方法 3、連分数法、手計算に適しています
実は、この方法はニュートン反復法と本質的には同じであり、微分が苦手な生徒にも適用できる方法であり、条件も比較的厳しいのが特徴です。
- 平方根のみ
- radicand は正の整数です。
手順は次のとおりです。s \sqrt{s}が必要です。s、まずそれをs = a 2 + bs = a^2 + bに分解します。s=ある2+b、ここでa 2 >> ba^2 >> bある2>>b、その後、必要な精度に従って
s = a + b 2 a + b 2 a + . . . \sqrt{s} = a + \frac {b} {2a + \frac {b} {2a + ...}}s=ある+2a + _2a + 。_ 。。bb
たとえば、150 の平方根を求めるには、まず150 = 12 ∗ 12 + 6 150 = 12 * 12 + 6を求めます。1 5 0=1 2∗1 2+6
- 一次状況150 = 12 \sqrt{150} = 12を求めます。1 5 0=1 2
- 2 次の場合、150 = 12 + 6 / 24 = 12.25 \sqrt{150} = 12 + 6/24 = 12.251 5 0=1 2+6 / 2 4=1 2 . 2 5、精度が高くなりました
- 3 次、150 = 12 + 6 / ( 24 + ( 6 / 24 ) ) = 12.2474 \sqrt{150} = 12 + 6/(24 + (6/24)) = 12.24741 5 0=1 2+6 / ( 2 4+( 6 / 2 4 ) )=1 2 . 2 4 7 4、少し高い
- …精度が深いほど精度が高くなります
電卓の150 \sqrt{150}をクエリします1 5 0の値は 12.24744 で、答えに非常に近いです。
証明方法も非常に簡単です。後で李永楽氏の関連する証明を投稿します。
参考文献
【1】ニュートンの平方根を求める反復法をわかりやすく説明するには?数値解析?- 学生馬の答え - Zhihu
[2]平方根を手動で計算するにはどうすればよいですか? これを学べば、また友達に自慢できます!