前から「sqrt」とかいう平方根を求める関数はどういう仕組みなのか知りたかったんですけど、
今日ある本を読んでたら、「ニュートン・ラフソン法」とかいうのがあったんで、やってみました
double Root(double square){
double denominator = 1;
double numerator = square;
double temp;
temp = 2 * numerator * denominator / square;
numerator = denominator * denominator + numerator * numerator / square;
denominator = temp;
for(int i = 0; i < 5; i++){
temp = 2 * numerator * denominator;
numerator = denominator * denominator * square + numerator * numerator;
denominator = temp;
}
return numerator / denominator;
}
最初の部分はなんというか、簡単にしてます
これがないと値の正確さが少し落ちる
じゃ、値の検証
方法は、各関数で平方根を求めてから、それを2乗するみたいなかんじで
値:10
自作Root:10
sqrt:10
値:100
Root:100.001
sqrt:100
値:1000
Root:1072.25
sqrt:10000
値:10000
Root:31335.4
sqrt:100000
値:100000
Root:2.50833e+006
sqrt:1000000
なんだこのザマは・・・
double型の値の範囲の問題を解決しないと、この関数はしっかりしたものにならなそうですね
ちなみにsqrt関数の方は、doubleの範囲内なら、誤差はありませんでした(多分)
・・・このあと、無駄に工夫せず、本来のニュートン・ラフソン法でプログラムしてみた
long double Root(double square){
long double a = square;
for(int i = 0; i < 8; i++){
a = (a + square / a) / 2;
}
return a;
}
_人人人人人人人人人_
> その結果がこれだよ<
 ̄^Y^Y^Y^Y^Y^Y ̄
値:1000
Root:1000
sqrt:1000
値:10000
Root:10241.9
sqrt:10000
値:100000
Root:223207
sqrt:1000000
こっちの方がいい・・・だと・・・
くそっ!!!!
<実行速度を比べてみた>
10000000回実行して、ミリ秒で計測しました
自作Root関数は、なんとなく速そうな後者のやつで
Root:598
sqrt:277
うわああああああああああ\(^o^)/
これが標準のすごさってやつか
Wikipedia見たら、求根アルゴリズムのページがあったので、それのブレント法とかを使ってるんじゃないですかね
それにしても、改良後のRoot関数より速いってどういうこっちゃ・・・
追記
マリオサンシャインのBGMは神ぞ!!!