Advertisement
Marrin

Calculating pi

Mar 5th, 2014
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.12 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4.  
  5. #define RADIUS  3000
  6. #define HIT_ZONE  ((double) RADIUS * RADIUS)
  7. #define HIT_ZONE_FIXPOINT  ((RADIUS * RADIUS) << 2)
  8.  
  9. typedef double (*calculate_pi)(void);
  10.  
  11.  
  12. double calculate_pi_a(void)
  13. {
  14.     uint16_t i, j;
  15.     double x, y;
  16.     uint32_t hit_count = 0;
  17.  
  18.     for (i = 0; i < RADIUS; ++i) {
  19.         x = i + 0.5;
  20.         x *= x;
  21.         for (j = 0; j < RADIUS; ++j) {
  22.             y = j + 0.5;
  23.             y *= y;
  24.             if (x + y <= HIT_ZONE) {
  25.                 ++hit_count;
  26.             }
  27.         }
  28.     }
  29.     return 4 * hit_count / HIT_ZONE;
  30. }
  31.  
  32.  
  33. double calculate_pi_b(void)
  34. {
  35.     uint16_t i, j;
  36.     double x, *values;
  37.     uint32_t hit_count = 0;
  38.  
  39.     values = malloc(RADIUS * sizeof(*values));
  40.     for (i = 0; i < RADIUS; ++i) {
  41.         x = i + 0.5;
  42.         values[i] = x * x;
  43.     }
  44.  
  45.     for (i = 0; i < RADIUS; ++i) {
  46.         for (j = 0; j < RADIUS; ++j) {
  47.             if (values[i] + values[j] <= HIT_ZONE) {
  48.                 ++hit_count;
  49.             }
  50.         }
  51.     }
  52.  
  53.     free(values);
  54.     return 4 * hit_count / HIT_ZONE;
  55. }
  56.  
  57.  
  58. double calculate_pi_c(void)
  59. {
  60.     uint16_t i, j;
  61.     double x, *values;
  62.     uint32_t hit_count = 0;
  63.  
  64.     values = malloc(RADIUS * sizeof(*values));
  65.     for (i = 0; i < RADIUS; ++i) {
  66.         x = i + 0.5;
  67.         values[i] = x * x;
  68.     }
  69.  
  70.     for (i = 0; i < RADIUS; ++i) {
  71.         for (j = i + 1; j < RADIUS; ++j) {
  72.             if (values[i] + values[j] <= HIT_ZONE) {
  73.                 ++hit_count;
  74.             }
  75.         }
  76.     }
  77.     hit_count *= 2;
  78.  
  79.     for (i = 0; i < RADIUS; ++i) {
  80.         if (values[i] * 2 <= HIT_ZONE) {
  81.             ++hit_count;
  82.         }
  83.     }
  84.  
  85.     free(values);
  86.     return 4 * hit_count / HIT_ZONE;
  87. }
  88.  
  89.  
  90. double calculate_pi_d(void)
  91. {
  92.     uint16_t i, j;
  93.     uint32_t *values;   /* Fixed point values with two bits fractional part. */
  94.     uint32_t hit_count = 0;
  95.  
  96.     values = malloc(RADIUS * sizeof(*values));
  97.     /*
  98.      * `j` is a fixed point value with one bit fractional part here.
  99.      * So it starts at 0.5 and is incremented by 1.0 each loop iteration.
  100.      */
  101.     for (i = 0, j = 1; i < RADIUS; ++i, j += 2) {
  102.         values[i] = j * j;
  103.     }
  104.  
  105.     for (i = 0; i < RADIUS; ++i) {
  106.         for (j = i + 1; j < RADIUS; ++j) {
  107.             if (values[i] + values[j] <= HIT_ZONE_FIXPOINT) {
  108.                 ++hit_count;
  109.             }
  110.         }
  111.     }
  112.     hit_count *= 2;
  113.  
  114.     for (i = 0; i < RADIUS; ++i) {
  115.         if (values[i] * 2 <= HIT_ZONE_FIXPOINT) {
  116.             ++hit_count;
  117.         }
  118.     }
  119.  
  120.     free(values);
  121.     return 4.0 * hit_count / (HIT_ZONE_FIXPOINT >> 2);
  122. }
  123.  
  124.  
  125. int main(int argc, char *argv[])
  126. {
  127.     uint i;
  128.     calculate_pi functions[] = {
  129.         calculate_pi_a, calculate_pi_b, calculate_pi_c, calculate_pi_d
  130.     };
  131.     uint function_count = sizeof(functions) / sizeof(calculate_pi);
  132.  
  133.     if (argc > 1 && sscanf(argv[1], "%u", &i) == 1 && i < function_count) {
  134.         printf("method %c: %f\n", 'a' + i, functions[i]());
  135.     } else {
  136.         printf("usage: %s [0-%u]\n", argv[0], function_count - 1);
  137.     }
  138.     return 0;
  139. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement