我在Cay Horstmann的书中遇到了这个问题:
编写以下模拟程序:将飞镖随机掷到 带有角(1,1)和(-1,-1)的正方形。如果飞镖落在单位圆内(即, 中心为(0,0)且半径为1)的圆是一个命中点。否则会很想念。运行这个 模拟并使用它来确定π的近似值。如果您有额外信用 解释为什么这是一种比Buffon针更好的π估计方法 程序。
我知道为什么这是一种比布冯针更好的π估计方法 程序,所以很好。但是我的代码似乎有问题。
这是我当前的代码:
import java.util.Scanner;
public class Dart {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter number of tries: ");
int n = in.nextInt();
int miss = 0;
int hit = 0;
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
double func = x * x + y * y;
for (int i = 0; i < n; i++) {
if (func <= 1) {
hit++;
} else {
miss++;
}
}
System.out.println("Probability: " + hit / (hit + miss) * 4);
}
}
当我输入任何数字时,概率输出始终显示为1,但是我认为如果代码正确,它会打印π,因为其:(半径为1的圆的面积)超过(长度为2的正方形)次4。
我希望能得到解释为什么我的代码是错误的。
答案 0 :(得分:1)
分配变量时,该变量不会在每次被请求时都重新计算-分配一次 ,直到重新分配之前,它始终是相同的值。所以这个:
double x = Math.random() * 2 - 1;
double y = Math.random() * 2 - 1;
double func = x * x + y * y;
将x和y设置为-1和1之间的随机数,并将func设置为x * x + y * y
...,然后它们将保持这种状态,直到程序结束,因为您再也没有分配它们。 / p>
所以这个:
for (int i = 0; i < n; i++)
{
if (func <= 1)
hit++;
else
miss++;
}
将始终增加hit
或增加miss
,因为func
的值永远不变。
您要做的是将x
,y
和func
的定义移至for循环的内部,而不是外部,这将使其每次都与您期望的不同。
此外,整数除法运算得出整数,因此您需要在最后一行将miss
和hit
转换为double
s。
答案 1 :(得分:0)
尝试以下方法
import java.util.Scanner;
public class Dart
{
public static void main(String[]args)
{
Scanner in = new Scanner(System.in);
System.out.println("Enter number of tries: ");
int n = in.nextInt();
double miss = 0;
double hit = 0;
double x = 0, y = 0, func = 0;
for (int i = 0; i < n; i++)
{
x = Math.random() * 2 - 1;
y = Math.random() * 2 - 1;
func = x * x + y * y;
if (func <= 1)
hit++;
else
miss++;
}
System.out.println("Probability: " + ( (double) hit / (hit + miss) * 4 ));
}
}
您犯了2个错误,第一个错误是您需要在循环内生成随机x和y,以便重新生成值,其次,您需要使用doubles
或floats
来实现命中率和未命中率,甚至更好方式(感谢@FedericoklezCullocafor),您可以将它们强制转换为print
内的双精度数,因为如果您在int
中向下使用print
,则会进行整数除法,该整数除法始终返回0。 / p>