- ベストアンサー
円周率の値を求める方法とは?
- 円周率の値を求める方法について質問があります。Nを大きくすると3.1415に近づくはずですが、うまくいきません。解決策を教えてください。
- 円周率の値を求めるプログラムを実行して、結果が得られました。Nの値を10から1000000まで変化させた結果、それぞれに対する近似値が表示されました。
- Nの値を大きくすると、円周率の近似値が徐々に3.1415に近づいていくことが分かります。しかし、どのような問題があるのか具体的にはわかりません。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
このソースをよく検討してみると(見当ではありません)、以下の2箇所を直せばよいことがわかります。 おかしいのは、以下のところです。 sum=0; ・・ここでクリアしてはいけない。 for(N=10;N<=1000000;N*=10){ for(i=10;i<N;i++){ ・・i=10 ではなく、i=0とする。 従って、以下のようにします。 srand((unsigned)time(NULL)); for(N=10;N<=1000000;N*=10){ sum=0; ・・・・・・・・ここでクリアする for(i=0;i<N;i++){ ・・・・i=0にする 上記のようにして実行してみて下さい。 ほぼ望んだ結果になります。
その他の回答 (4)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス >円周率πの値を求めたのですがNを大きくすると3.1415・・・に近づくはずですが、うまくいきません。 ↑ 擬似乱数を使っているので上手くいくときとそうでない場合があるからでしょう。 それかfloat型よりもdouble型の方が有効桁数が多い分だけ精度が出ませんか? あるいはNをかなり大きくしないと精度がでないとか? ・私もちょっと作ってみました。 私は unsigned long long 型で試しました。 サンプル: #include <time.h> #include <stdio.h> #include <stdlib.h> // ベース定数 #define BASE 1000000000LL // 擬似乱数 unsigned long long myrand( void ) { return ((unsigned long long)rand() * rand() * rand() * rand()) % BASE; } // メイン関数 int main( void ) { unsigned long N, pi, i, sum; unsigned long long x, y, r; srand( (unsigned)time(NULL) ); for ( N = 10 ; N <= 10000000 ; N *= 10 ){ for ( sum = i = 0 ; i < N ; i++ ){ x = myrand(); y = myrand(); r = (x * x) + (y * y); if ( r < (BASE * BASE) ){ sum++; } } pi = (sum * 4); printf( "%8lu %lu\n", N, pi ); } return 0; } 実行結果(例): 10 32 100 332 1000 3148 10000 31364 100000 314236 1000000 3143132 10000000 31415956 4回実行したうちの1つです。 最初に実行した時間が精度が良かったみたいです。 覚えていませんが…。
- Tacosan
- ベストアンサー率23% (3656/15482)
処理系によるところもあるんだけど, もっとまともな疑似乱数発生器使ってみるとか.
- asuncion
- ベストアンサー率33% (2127/6289)
ぜい肉を少しそぎ落としてみました。 ついでに、 × 検討がつきません ○ 見当がつきません #include <stdio.h> #include <stdlib.h> #include <time.h> double myrand(void) { return (double) rand() / RAND_MAX; } int main(void) { int i, sum, n; double x, y; srand((unsigned) time(NULL)); for (n = 10; n <= 1000000; n *= 10) { for(sum = i = 0; i < n; i++) { x = myrand(); y = myrand(); if (x * x + y * y < 1.0) sum++; } printf("%d %f\n", n, 4.0 * sum / n); } return 0; } (注)インデントのため、全角空白を使っています。
- Werner
- ベストアンサー率53% (395/735)
> for(i=10;i<N;i++){ このループの開始時にsumが0になっていません。 (なぜiが10から始まるのかも疑問だが。) あと、Nがlongなのにiやsumがintでいいの?