java for-loop problem

2020-04-11 14:29发布

I am making a Java program to calculate Simpson's rule for integrals. Here is the code I have. Notice the second column of numbers in the output values of count == 4,9,10,11. They are not numbers that I need, they do not follow the pattern. I need these numbers to be accurate. What is going on and how can I fix it?

public static void main(String[] args) 
{
   double totalS = 0.0;
   int count = 0;

   for(double i=0; i< 4; i += 0.4 )
   {
          count++;
          totalS += Sfunction(i, count);
          System.out.println(count + " " + i + " " + totalS);
   }
}

public static double Sfunction(double f1, int count)
{
    double value;

    if (f1 == 0.0 || f1 == 4.0)
        value = Math.cos(Math.sqrt(f1));
    else if ((count % 2) == 1)
        value = 2 * Math.cos(Math.sqrt(f1));
    else
        value = 4 * Math.cos(Math.sqrt(f1));

    return value;
}

I get the output of:

1    0.0    1.0 
2    0.4    4.226313639540303
3    0.8    5.478244888601832
4    1.2000000000000002    7.30884788480188
5    1.6    7.911122809972827
6    2.0    8.534897589034324
7    2.4    8.578100205110182
8    2.8    8.168723348285942
9    3.1999999999999997    7.736055200662704
10   3.5999999999999996    6.452869366954546
11   3.9999999999999996    5.620575693860261

标签: java for-loop
8条回答
趁早两清
2楼-- · 2020-04-11 15:09

This is a classic floating point problem. If you need accuracy in your decimals, you should be using BigDecimal

查看更多
兄弟一词,经得起流年.
3楼-- · 2020-04-11 15:10

Your problem is that you are using floating point arithmetic which can only approximate values, but assuming you have infinite precision. You shouldn't do equality tests like this with floating point numbers:

 if (f1 == 0.0 || f1 == 4.0)

Any equality test with a floating point number is a code smell. With a float you should always check if it lies within a certain range, for example in the range 3.9999 to 4.0001.

In this specific example though, you also handily have another parameter called count which is an int. You can do equality tests with that. Maybe you can test that instead.

查看更多
登录 后发表回答