为什么在使用余数运算符对双精度数进行操作时会返回错误?

huangapple go评论74阅读模式
英文:

Why does using the remainder operator with a double return false?

问题

public static void main(String[] args) {
    double s = 0; // 位置
    double v = 100; // 速度
    double g = 9.81; // 重力

    for (double time = 0.01; time < 100; time = time + 0.01) {
        double DELTA_T = 0.01;
        s = s + (v * DELTA_T);
        v = v - (g * DELTA_T);

        if (time % 1 == 0) { // 我希望将此输出,但似乎程序在没有输出的情况下就结束了
            System.out.println("秒数:" + time);
            System.out.println("位置:" + s);
            System.out.println("速度:" + v);
        }
    }
}
英文:
 public static void main(String[] args) {
    double s = 0; //Position
    double v = 100; //Velocity
    double g = 9.81; //Gravitational Force

    for(double time = 0.01; time &lt; 100; time = time + 0.01){
       double DELTA_T = 0.01;
        s = s + (v * DELTA_T);
        v = v - (g * DELTA_T);

        if(time % 1 == 0) { //I want to print this out, but it seems to end the program with no output
            System.out.println(&quot;Seconds: &quot; + time);
            System.out.println(&quot;Position: &quot; + s);
            System.out.println(&quot;Velocity: &quot; + v);
        }
    }
}

I want to output the calculations when (time % 1 == 0). But when I run this, it doesn't print anything out. When I remove the if statement, and leave in the print statements, it will print.

I was wondering what is wrong with my if statement and how would I go about trying to print "s", "v", and "time" every time (time % 1 == 0)

答案1

得分: -1

这里的问题很可能是因为您在比较浮点数值的相等性。请参阅 https://stackoverflow.com/questions/588004/is-floating-point-math-broken 了解有关浮点数学和相等性比较所遇到的问题。

针对您的具体问题,我建议您使用一个表示百分之一秒的整数计数器。然后,您可以使用整数进行比较:



 public static void main(String[] args) {
    double s = 0; //位置
    double v = 100; //速度
    double g = 9.81; //重力

    for(int time = 1; time &lt; 10000; time++) {
        double DELTA_T = 0.01;
        s = s + (v * DELTA_T);
        v = v - (g * DELTA_T);

        if(time % 100 == 0) { //我想将此打印出来,但似乎会结束程序而没有输出
            System.out.println(&quot;秒数:&quot; + time);
            System.out.println(&quot;位置:&quot; + s);
            System.out.println(&quot;速度:&quot; + v);
        }
    }
}

这将解决您的打印问题。然而,您很可能会注意到 sv 的值不正确。这是因为在每次迭代中在浮点数学中积累了误差。您应该直接从每次迭代的 time 计算这些值,而不是目前的方式。

英文:

The problem here is most likely because you are comparing equality of floating point values. See https://stackoverflow.com/questions/588004/is-floating-point-math-broken for an introduction to the problems we encounter with floating point math and equality comparison.

For your specific problem, I suggest that you use an integer counter that represents hundredths of a second. Then you can do your comparison with integers instead:



 public static void main(String[] args) {
    double s = 0; //Position
    double v = 100; //Velocity
    double g = 9.81; //Gravitational Force

    for(int time = 1; time &lt; 10000; time++) {
        double DELTA_T = 0.01;
        s = s + (v * DELTA_T);
        v = v - (g * DELTA_T);

        if(time % 100 == 0) { //I want to print this out, but it seems to end the program with no output
            System.out.println(&quot;Seconds: &quot; + time);
            System.out.println(&quot;Position: &quot; + s);
            System.out.println(&quot;Velocity: &quot; + v);
        }
    }
}

This will solve your printing problem. However, you will most like see that s and v will not have the correct values. This is because you are accumulating errors in the floating point math over each iteration. You should calculate these directly from time on each iteration, rather than the way you are doing it now.

答案2

得分: -1

你的时间变量精度影响了取模检查。你需要进行乘法并转换为整数以获得正确的结果:

public static void main(String[] args) {
    double s = 0; // 位置
    double v = 100; // 速度
    final double g = 9.81; // 重力
    final double DELTA_T = 0.01;

    for (double time = 0.01; time < 100; time += 0.01) {
        s += (v * DELTA_T);
        v -= (g * DELTA_T);

        System.out.println(time);
        if (((int) (time * 100)) % 100 == 0) {
            System.out.println("秒数: " + time);
            System.out.println("位置: " + s);
            System.out.println("速度: " + v);
        }
    }
}
英文:

Your time variable precision is ruining your modulo check. You need to multiply and cast to an int get a good result:

public static void main(String [] args {
	double s = 0; //Position
    double v = 100; //Velocity
    final double g = 9.81; //Gravitational Force
    final double DELTA_T = 0.01;

    for(double time = 0.01; time &lt; 100; time += 0.01){
        s += (v * DELTA_T);
        v -= (g * DELTA_T);

        System.out.println(time);
        if (((int) (time * 100)) % 100 == 0) { 
            System.out.println(&quot;Seconds: &quot; + time);
            System.out.println(&quot;Position: &quot; + s);
            System.out.println(&quot;Velocity: &quot; + v);
        }
    }
}

huangapple
  • 本文由 发表于 2020年3月4日 04:23:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/60514956.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定