我正在编写一个C程序,该程序将能够接受一个输入值,该值指示将用于估计Pi的迭代次数。
例如,随着迭代次数的增加,要创建的点的数量也会增加,Pi的值也会增加。
这是我迄今为止的代码:
#include <stdio.h>
#include <stdlib.h>
main()
{
const double pp = (double)RAND_MAX * RAND_MAX;
int innerPoint = 0, i, count;
printf("Enter the number of points:");
scanf("%d", &innerPoint);
for (i = 0; i < count; ++i){
float x = rand();
float y = rand();
if (x * x + y * y <= 1){
++innerPoint;
}
int ratio = 4 *(innerPoint/ i);
printf("Pi value is:", ratio);
}
}
在我面临程序错误时帮助修复我的代码。
rand()
返回一个整数[0...RAND_MAX]
。
所以类似于:
float x = rand()*scale; // Scale is about 1.0/RAND_MAX
蒙特卡罗方法的质量取决于一个好的随机数生成器。rand()
可能没有那么好,但让我们假设它是一个公平的随机数生成器。
[0...RAND_MAX]
的范围是RAND_MAX+1
的不同值,应从[0.0…1.0]均匀分布。
CCD_ 6将端点偏移0.0和1.0,使它们的权重是其他端点的两倍。
考虑[0.5, 1.5, 2.5, ... RAND_MAX + 0.5]/(RAND_MAX + 1)
。
RAND_MAX
可能超过float
的精度,因此将rand()
或RAND_MAX
(均为int
(转换为float
可能导致舍入并进一步干扰蒙特卡罗方法。以double
为例。
#define RAND_MAX_P1 ((double)RAND_MAX + 1.0)
// float x = rand();
double x = ((double) rand() + 0.5)/RAND_MAX_P1;
x * x + y * y
也可能导致过度舍入。C具有CCD_ 16以获得更好的精度CCD_。然而,在这里,对于小的count
,它可能没有明显的差异。
// if (x * x + y * y <= 1)
if (hypot(x, y <= 1.0))
我确信这不是最好的解决方案,但它应该能完成任务,并且与您的代码类似。使用至少10000的样本大小来获得接近PI的值。
正如评论中提到的:您应该查看返回值函数给您的数据类型。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
// Initialize random number generation
srand(time(NULL));
int samples = 10000;
int points_inside =0;
// Read integer - sample size (use at least 10000 to get near PI)
printf("Enter the number of points:");
scanf("%d", &samples);
for (int i = 0; i < samples; ++i){
// Get two numbers between 0 and 1
float x = (float) rand() / (float)RAND_MAX;
float y = (float) rand() / (float)RAND_MAX;
// Check if point is inside
if (x * x + y * y <= 1){
points_inside++;
}
// Calculate current ratio
float current_ratio = 4 * ((float) points_inside / (float) i);
printf("Current value of pi value is: %f n", current_ratio);
}
}