fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <time.h>
  5.  
  6. #define NUM_POINTS 1000000 // 最大乱数の個数
  7. #define TRUE_AREA (M_PI - 3 * sqrt(3) + 3) / 3 // 真の面積
  8. #define NUM_STEPS 12 // 横軸の乱数の個数を12個に制限
  9.  
  10. // 2つの円の内部にあるかどうかを判定する関数
  11. int is_inside(double x, double y) {
  12. double r = 1.0;
  13. // 円1:中心(0,1)、半径1
  14. if ((x - 0) * (x - 0) + (y - 1) * (y - 1) <= r * r &&
  15. // 円2:中心(1,0)、半径1
  16. (x - 1) * (x - 1) + (y - 0) * (y - 0) <= r * r) {
  17. return 1;
  18. }
  19. return 0;
  20. }
  21.  
  22. int main() {
  23. int i, inside_count = 0;
  24. double x, y;
  25. double estimated_area;
  26. double error;
  27. int step_size = NUM_POINTS / NUM_STEPS; // 乱数の個数を12ステップに分割
  28.  
  29. // 乱数の生成を初期化
  30. srand(time(NULL));
  31.  
  32. // タイトルを出力(列名として表示される)
  33. printf("乱数の個数,誤差\n");
  34.  
  35. // Monte Carlo法で面積を近似する
  36. for (i = 1; i <= NUM_POINTS; i++) {
  37. // 0から1の範囲で乱数を生成
  38. x = (double)rand() / RAND_MAX;
  39. y = (double)rand() / RAND_MAX;
  40.  
  41. // 円の内部にあるかどうかを判定
  42. if (is_inside(x, y)) {
  43. inside_count++;
  44. }
  45.  
  46. // 12等分されたステップごとに誤差を計算して出力
  47. if (i % step_size == 0) {
  48. estimated_area = 4.0 * (double)inside_count / i; // 4倍するのは単位正方形全体の面積が1×1なので
  49. error = fabs(estimated_area - TRUE_AREA);
  50.  
  51. // カンマ区切りで乱数の個数と誤差を出力
  52. printf("%d,%f\n", i, error);
  53. }
  54. }
  55.  
  56. printf("計算が完了しました。\n");
  57.  
  58. return 0;
  59. }
  60.  
Success #stdin #stdout 0.04s 5280KB
stdin
Standard input is empty
stdout
乱数の個数,誤差
83333,1.966542
166666,1.968582
249999,1.965742
333332,1.967226
416665,1.968990
499998,1.966654
583331,1.966488
666664,1.964862
749997,1.965257
833330,1.963955
916663,1.964539
999996,1.964854
計算が完了しました。