• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Accuracy problems stemming from java.lang.Math trigonometry use.

 
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
-The following little program should issue the number 1.0 precisely,
but doesn't.

import static java.lang.Math.*;
import static java.lang.System.*;




-If I just plain must have the accuracy of the forward and inverse trigonometry functions,
is there a way inside the default Oracle Java libs that I can fix this to get trigonometry
accuracy back, without trying to patch around the calls?  For both the foward
and inverse sine, cos, tan , asin, acos, atan functions?

-If not, is there a free use/open source lib that most people, or myself,
can and should go to?

 
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Don't know why mine works and yours doesn't.
 
Sergio Minervini
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
My question is not a about the fact that the method returns a value at all.

Is there someone else who can tell me what I can do about this lack of accuracy in this case?
Harking back to what I typed for this question at the start of this thread?

The answer should be an absolute 1.0 here.
 
Carey Brown
Saloon Keeper
Posts: 10705
86
Eclipse IDE Firefox Browser MySQL Database VI Editor Java Windows ChatGPT
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In floating point arithmetic there is no absolute. I suggest reading the IEEE specification on the subject. See also Wikipedia.

Also my output was 0.999..... and you say yours is 0.499......
 
Greenhorn
Posts: 17
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello, floating point numbers are not exact by nature, there are rounding errors. The answer is 0.999999999999999998 due to these rounding errors. It's very close to 1, but it's not equal to 1.

Because of these rounding errors, it is delicate to compare two floating-point numbers for equality. If you would like to compare the result with 1, for example, you should consider that the result is not exact and make a comparison, not by 1, but by something close to 1. For example:

       if ( abs(result-1) < 0.00001 ) {
           out.println("The answer is correct");
       }
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That IS an accurate result. You can't expect exact results to an infinite number of decimal places and the API documentation says so:

The docs for java.Math wrote:The computed result must be within 1 ulp of the exact result. Results must be semi-monotonic.



Notice that your first line of calculations should return half of the square root of two. But they can't do that because that's an irrational number. You're going to get an approximation, there's no way around it. And there's no way your second line of calculation can undo that approximation and return the exact value you're looking for.

And all algorithms which compute trigonometric functions are like that. It's not like the creators of Java decided to palm off a second-rate algorithm on you. For a (rather long) write-up on how this sort of algorithm is regarded by practical users: Numerical analysis.
 
Sergio Minervini
Ranch Hand
Posts: 51
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
-That is all fair enough, certainly as it goes.  I have tried using Apache Commons Math's FastMath
class and encounter exactly the same margin of value error.

-I am aware of the typo about predicted ouput in my original post.

-Can someone please recommend a public domain/free/open source
java library for evalutating trigonometry using java doubles
that won't leave these kinds of value approach errors,
but is more accurate given the limit number of Decimal places
that Double and double will ultimately have?
 
Paul Clapham
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm willing to bet there isn't one. You might find a library which notices special cases like the one you've highlighted, but it isn't going to use an algorithm which uses Java double values.
 
German Martinez
Greenhorn
Posts: 17
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There is no such library, floating point operations are by nature inaccurate. With a more accurate library you can have more precision digits, but you will always have an error. The error will be minor, but it will still be there.

It is as if you want to have an exact representation of 1/3 with 4 decimal digits of precision, you can't. 1/3 would be represented as 0.3333, and not as 0.3333333333333333... (to infinity).

A hand-held calculator has about 10 digits of precision, the double precision representation of computers has about 15 digits of precision. The CPU internally has about 18 digits of precision. There are libraries with thousands or millions of precision digits. If in your problem you want an exact 1 you need a real number, which has infinite digits of precision. In physical computers that doesn't exist.

With floating point numbers, equality is not guaranteed. You should always handle small (or large) accuracy errors. What you can do is learn to deal with these problems of imprecision (as I explained in the previous post).
 
Paul Clapham
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch, German!
reply
    Bookmark Topic Watch Topic
  • New Topic