所以基本上,我有一个变量time
,并希望程序每隔一秒打印其他值。
例如,如果我插入100,它应该只打印20秒。
import java.util.Scanner;
public class CannonBlaster {
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
final double DELTA_T = 0.01; //initiating all variables
final double G = 9.81;
double s = 0.0;
double time = 0.0;
double second = 0;
System.out.println("What's the initial velocity?: ");//asking for the initial velocity
double v =input.nextDouble();
while (s >= 0.0) //while loop is used. As long as the height isn't negative it will continue to go.
{
s += v * DELTA_T; //demonstrates the change of velocity and position for every .01 second.
v -= G * DELTA_T;
time += DELTA_T;
System.out.println("The time is: "+time+" "+(double) Math.floor(time)+" "+Math.round(time * 1000) / 1000);
second=Math.round(time * 1) / 1;
if ((double) Math.floor(time) ==time)
{
System.out.println("Approximated position: "+ s);
System.out.println("Formula's position: "+(100.0 * time - (time*time * G) / 2.0)); //prints out the formula values and the loop values.
}
}
}
请原谅这个烂摊子,我只是尝试了不同的方式去上班,但到目前为止都找不到。
答案 0 :(得分:0)
问题是double没有你想要的那种精确度,所以它的输出清楚地显示,每次迭代都不算偶数.01。解决方案是使用BigDecimal。我重写了一下程序......
package test;
import java.math.BigDecimal;
import java.util.Scanner;
public class CannonBlaster {
private static final double G = 9.81;
private static final BigDecimal DELTA_T = new BigDecimal(0.01);
private static final double DELTA_T_DOUBLE = DELTA_T.doubleValue();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
double s = 0.0;
BigDecimal time = new BigDecimal(0.0);
double time_double = 0.0;
System.out.println("What's the initial velocity?: ");// asking for the
// initial
// velocity
double v = input.nextDouble();
// As long as the height isn't negative it will continue to go.
while (s >= 0.0)
{
s += v * DELTA_T_DOUBLE;
v -= G * DELTA_T_DOUBLE;
time = time.add(DELTA_T);
time_double = time.doubleValue();
if (time.doubleValue()%1==0) {
System.out.printf("Approximated position at t=%3ds is %10.6f.\n", time.intValue(), s);
// prints out the formula values and the loop values.
System.out.println("Formula's position: " + formula(time_double));
}
}
}
private static double formula(double x){
return 100.0 * x - (x * x * G) / 2.0;
}
}
答案 1 :(得分:0)
问题在于,您的时间步长DELTA_T
并不能完全代表double
值。每次迭代都会累积这个小错误,您可以在打印出来的time
值中看到这一点。
通常最好在比较两个浮点数时通过将两个数字之间的绝对差值与某个“小”值进行比较来避免此问题,其中“小”由您正在使用的数字的问题/数量来定义。 DELTA_T
非常适合这里,因此您可以将此比较用于每秒时间步骤:
if (Math.abs(time - Math.round(time)) < DELTA_T)
{
// Other code here
}
或者,对于更广义的时间步骤,在PRINT_INTERVAL
:
final double PRINT_INTERVAL = 0.1;
// Other code...
if (Math.abs(time / PRINT_INTERVAL - Math.round(time / PRINT_INTERVAL)) < DELTA_T)
{
// Other code here
}