Home arrow static arrow Java Programming [Archive] - Math calculation error.
Warning: Creating default object from empty value in /www/htdocs/w008deb8/wiki/components/com_staticxt/staticxt.php on line 51
Java Programming [Archive] - Math calculation error.
This topic has 21 replies on 2 pages.    1 | 2 | Next »

Posts:5
Registered: 7/20/04
Math calculation error.  
Jul 20, 2004 10:15 AM



 
When I run following code I got result: 1.1399999999999997 == 1.14, witch is not correct because those calculations shoud give the same result (1.14). Any ideas how to handle this kind of situation?
public class CalculationTester {    public static void main(String[] args) {                double a = 1.6666666666666667;        double b = 0.03333333333333333;        double c = 2.975;        double d = 0.005;        double e = 65.0;        double f = 467.0;        double g1 = 1.0;        double g2 = -1.0;            double result1 = -(a - (b * e) - c + (d * f)) / g1;                double result2 = -(c - (d * f) - a + (b * e)) / g2;                           System.out.println(result1 + " == " + result2);            }}

So what to do? Should I write that calculation part using c++ and rest with Java or just forget the Java? This code need to be fast, because it is critical part of simulation.

Code with values:
result1  = -(1.6666666666666667 - (0.03333333333333333 * 65.0) - 2.975 + (0.0050 * 467.0)) / 1.0;result2  = -(2.975 - (0.0050 * 467.0) - 1.6666666666666667 + (0.03333333333333333 * 65.0)) / -1.0;===> result1 = -1.6666666666666667 + (0.03333333333333333 * 65.0) + 2.975 - (0.0050 * 467.0)result2 = 2.975 - (0.0050 * 467.0) - 1.6666666666666667 + (0.03333333333333333 * 65.0)===>result1 = 2.975 - (0.0050 * 467.0) - 1.6666666666666667 + (0.03333333333333333 * 65.0)result2 = 2.975 - (0.0050 * 467.0) - 1.6666666666666667 + (0.03333333333333333 * 65.0)
 

Posts:929
Registered: 9/30/02
Re: Math calculation error.  
Jul 20, 2004 10:20 AM (reply 1 of 21)



 
Unfortunately, this is a problem in how floating point numbers are stored in a binary computer (IEEE floating point format). There is not much you can really do without making a rounding method.
 

Posts:11,200
Registered: 7/22/99
Re: Math calculation error.  
Jul 20, 2004 10:21 AM (reply 2 of 21)



 
This "issue" is language independent. Write the same thing in C++ and observe the same result.
http://docs.sun.com/source/806-3568/ncg_goldberg.html
 

Posts:5
Registered: 7/20/04
Re: Math calculation error.  
Jul 20, 2004 10:27 AM (reply 3 of 21)



 
I have done the same using c++ and the result is 1.14 == 1.14.

This is part of program witch I ported to java and then the problems started. At lest pascal and c++ works just fine.

[code]
#include <iostream>

int main() {

double a = 1.6666666666666667;
double b = 0.03333333333333333;
double c = 2.975;
double d = 0.005;
double e = 65.0;
double f = 467.0;
double g1 = 1.0;
double g2 = -1.0;

double result1 = -(a - (b * e) - c + (d * f)) / g1;
double result2 = -(c - (d * f) - a + (b * e)) / g2;

std::cout << result1 << " == " << result2 << std::endl;

return 0;
}
[code]
 

Posts:24,036
Registered: 2/3/03
Re: Math calculation error.  
Jul 20, 2004 10:32 AM (reply 4 of 21)



 
IIRC, those languages don't show the full precision. You need to read the article. Java works "just fine", too.
 

Posts:24,036
Registered: 2/3/03
Re: Math calculation error.  
Jul 20, 2004 10:35 AM (reply 5 of 21)



 
double x = 1.3;System.out.println(x + x + x); // 3.9000000000000004
 

Posts:31,095
Registered: 4/30/99
Re: Math calculation error.  
Jul 20, 2004 10:36 AM (reply 6 of 21)



 
I get 1.13999999999999975 with my Windows calculator. If C++ is saying that the answer is 1.14 then it must be rounding it before it says that. Anyway, you have no business complaining about accuracy when you used rough approximations to 5/3 and 1/30.
 

Posts:11,200
Registered: 7/22/99
Re: Math calculation error.  
Jul 20, 2004 10:41 AM (reply 7 of 21)



 
As you see from Java's output, the difference between the two results is very small, so you need to increase the precision a lot. The default precision of cout shows only 4 decimals and rounds the number. Try these modifications to your code:
        std::cout.precision(20);        std::cout << result1 << " == " << result2 << std::endl;        std::cout << (result1 == result2) << std::endl;
Your results vary depending on the compiler and optimization level.
tmp> g++ number.cpp -o number -O0
tmp> ./number
1.1399999999999999 == 1.1399999999999999
1
tmp> g++ number.cpp -o number -O2
tmp> ./number
1.1399999999999997 == 1.1399999999999999
0
 

Posts:5
Registered: 7/20/04
Re: Math calculation error.  
Jul 20, 2004 10:46 AM (reply 8 of 21)



 
The case is following.

I don't print anything in that simulation. After those calculations there is:
if ((result1 < result2)	|| (........) { }


And in that part I just pick that case to result set. So when running same simulation in pascal I got less results what I got with java.

Those values are calculated from double [][] array and other values are also double values.

So it seems now that Java might not be the correct language to my problem. Originally that code is writed with pascal and I just ported that code to Java.

I test to write that calculation part using c++ and calling it from Java code. I write it here how it work ;)
 

Posts:447
Registered: 3/8/01
Re: Math calculation error.  
Jul 20, 2004 10:50 AM (reply 9 of 21)



 
C++ automatically rounds numbers to about 6 decimal places when you use cout. Use printf("%.20f", yourNumber) to see all the digits. Alternatively, in Java, use DecimalFormat to print at most 6 decimal places, and the problem will mysteriously go away :).
 

Posts:329
Registered: 1/6/04
Re: Math calculation error.  
Jul 20, 2004 10:51 AM (reply 10 of 21)



 
Sun has a tech tip article on dealing with floating point arithmetic that might interest you:
http://java.sun.com/developer/JDCTechTips/2003/tt0204.html#2
 

Posts:5
Registered: 7/20/04
Re: Math calculation error.  
Jul 20, 2004 10:59 AM (reply 11 of 21)



 
double x = 1.3;double xx = x * 3;double xxx = x + x + x;if(xx == 3.9 || xxx == 3.9) {    System.out.println("Hello World!");}System.out.println(x);System.out.println(xx);System.out.println(xxx);

Result:
1.3
3.9000000000000004
3.9000000000000004

 

Posts:11,200
Registered: 7/22/99
Re: Math calculation error.  
Jul 20, 2004 11:27 AM (reply 12 of 21)



 
This is not a bug. Floating point operations are inherently imprecise and for that reason you should never ever in any programming language compare two floating point values without using a treshold.

If you find that the way you've implemented your algorithm works in Pascal with your Pascal compiler with your compiler settings on your microprocessor, good for you but that doesn't mean that the result would be the same when you port it to a different language and use a different compiler. Like I demostrated, the what happens with Java happens with your C++ code if you happen to compile it with optimizations enabled.

Instead of a==b you should use something like Math.abs(a-b) < epsilon for some small epsilon, and instead of a<b use b-a > epsilon, and so on.
 

Posts:24,036
Registered: 2/3/03
Re: Math calculation error.  
Jul 20, 2004 11:31 AM (reply 13 of 21)



 
So it seems now that Java might not be the correct
language to my problem.

This is a problem inherent to computers and how they handle floating-point precision. Read the article.
 

Posts:37,103
Registered: 3/30/99
Re: Math calculation error.  
Jul 20, 2004 11:32 AM (reply 14 of 21)



 
and
instead of a epsilon, and so on.

Interesting.

I know about using epsilon for the equality test, but I wasn't aware of this use of it for inequalities. Why is this necessary?
 
This topic has 21 replies on 2 pages.    1 | 2 | Next »