- 平方根を数え上げ法で求めるコードを作成し, 実用性検討した.
- 平方根を区間2分法で求めるコードを作成し, 繰り返し回数を検討した.
- 平方根をニュートン法で求めるコードを作成し, 繰り返し回数を検討した.
- c言語で書いてみたいと思う自分にとって興味深い題材をプログラムとして作成した.
レポート巻末に記載しました。結果は以下のようになりました。
value: 1, enum: 1.0000009999999999177, bin: 0.9999999999, ntn: 1
value: 10, enum: 3.1622800000000004239, bin: 3.16227766, ntn: 3.16227766
value: 100, enum: 10.000099999999999767, bin: 10, ntn: 10
value: 1000, enum: 31.623000000000001108, bin: 31.6227766, ntn: 31.6227766
value: 10000, enum: 100.01000000000000512, bin: 100, ntn: 100
value: 100000, enum: 316.30000000000001137, bin: 316.227766, ntn: 316.227766
まず、入力した配列とラムダ関数に対してfor文を実行するeach関数を定義しました。 これによって、コードの可読性が上がったと考えられます。 1~100000までテストしたところ、ntnsqrt関数はほとんど正確な値を計算できました。 bin関数は稀に小さい数を返すことがあることがわかりました。
#include <stdio.h>
#define N 1000000
#define EPSILON 1e-10
void each (int self[], int from=0, auto fun=[]{}) {
for (int i = 0; i < from; i++) fun(self[i], i);
}
double enumsqrt(double x, int i=1) {
double dx = x/N, t = dx;
for (; ; t=i++*dx) if (t*t-x>0) return t;
}
double binsqrt(double x) {
double a = 0.0, b = x, c = x;
for (; ; (c*c-x<0?a:b)=c=a/2+b/2) if (b-a<EPSILON) return a;
}
double ntnsqrt(double x) {
double a = x, b = 2*x;
for (; ; a=(b=a)/2+x/2/a) if (b-a<EPSILON) return a;
}
int main(void) {
int cases[] = {1, 10, 100, 1000, 10000, 100000};
each(cases, 6, [](int v, int i){
printf("value: %i, ", v);
printf("enum: %.20g, ", enumsqrt(v));
printf("bin: %.10g, ", binsqrt(v));
printf("ntn: %.10g\n", ntnsqrt(v));
});
return 0;
}