ネタ元 → あれ?
平方根: Math.Sqrt の引数は double なので decimal の平方根はどないすんの? と。
さてさてどーしましょ。ニュートン法でも使ってみましょか。
ニュートン法: f(x) = 0 の近似解を X とすると、
X - f(X)/f'(X) はより正確な近似解となる。 …[1]
√n を求めるってことは、
f(x) = x^2 - n としたときの f(x) = 0 の解を求めるってことです。
f'(x) = 2x ですから、f(x), f'(x) を [1] にぶっこんで:
class Program {
delegate decimal func(decimal x);
delegate decimal dfunc(decimal x);
static decimal newton(decimal x, func f, dfunc df) {
return x - f(x)/df(x);
}
public static void Main() {
decimal n = 2m;
decimal result = n;
for ( int i = 0; i < 10; ++i ) {
result = newton(result,
delegate(decimal x) { return x*x - n; },
delegate(decimal x) { return x+x; });
System.Console.WriteLine(result);
}
}
}
実行結果:
1.5
1.4166666666666666666666666667
1.4142156862745098039215686275
1.4142135623746899106262955789
1.4142135623730950488016896235
1.4142135623730950488016887242
1.4142135623730950488016887242
1.4142135623730950488016887242
1.4142135623730950488016887242
1.4142135623730950488016887242
5,6回通せば十分な精度が得られそうね。
[追記] あそっか。
近似解の初期値として Math.Sqrt(n) を与えれば:
public static void Main() {
decimal n = 2m;
decimal result = (decimal)System.Math.Sqrt((double)n);
…以下おなじ
一回通しただけで収束しちゃいますた♪