Double precision in general programming and Java

I understand that due to the nature of float / double, you cannot use them for accurate, important calculations. Nevertheless, I was a little confused in my limitations due to mixed answers to such questions, regardless of whether they will swim and double or not, it will always be inaccurate, regardless of significant numbers or only inaccurate up to the 16th digit.

I have done some examples in Java,

System.out.println(Double.parseDouble("999999.9999999999"); // this outputs correctly w/ 16 digits System.out.println(Double.parseDouble("9.99999999999999"); // This also outputs correctly w/ 15 digits System.out.println(Double.parseDouble("9.999999999999999"); // But this doesn't output correctly w/ 16 digits. Outputs 9.999999999999998 

I cannot find a link to another answer that states that values ​​such as 1.98 and 2.02 are rounded to 2.0 and therefore create inaccuracies, but testing shows that the values ​​print correctly. So, my first question is whether floating point or double values ​​will always be inaccurate or is there a lower limit where you can be sure of accuracy.

My second question is about using BigDecimal. I know that I have to use BigDecimal for accurate important calculations. Therefore, I have to use BigDecimal methods for arithmetic and comparison. However, BigDecimal also includes a doubleValue() method, which converts BigDecimal to double. Would it be safe for me to compare double values ​​that I know have less than 16 digits? Arithmetic will not be on them at all, so the inherent values ​​should not have changed.

For example, is it safe for me to do the following?

 BigDecimal myDecimal = new BigDecimal("123.456"); BigDecimal myDecimal2 = new BigDecimal("234.567"); if (myDecimal.doubleValue() < myDecimal2.doubleValue()) System.out.println("myDecimal is smaller than myDecimal2"); 

Edit: After reading some answers to my own answer, I realized that my understanding was wrong and deleted it. Here are some snippets that may help in the future.

"A double cannot exactly hold 0.1. The closest represented value to 0.1 is 0.1000000000000000055511151231257827021181583404541015625. Java Double.toString prints enough numbers to uniquely identify a double, not an exact value." - Patricia Shanahan

Sources:
stack overflow.squite

+4
source share
2 answers

I suggest you read this page:
https://en.wikipedia.org/wiki/Double-precision_floating-point_format

After you have read and understood it, and possibly translated a few examples into your binary representations in 64-bit floating point format, then you will have a much better idea of ​​what significant bits Double may contain.

+2
source

As a side note (perhaps trivial), a good and reliable way to store a known accuracy of a value is to simply multiply it by the appropriate factor and save it as some kind of integral type that is completely accurate.

For instance:

 double costInPounds = <something>; //eg 3.587 int costInPence = (int)(costInPounds * 100 + 0.5); //359 

Obviously, some accuracy may be lost, but if the required / desired accuracy is known, it can save a lot of floating point problems, and once this is done, no accuracy can be lost during further manipulations.

+ 0.5 should ensure that rounding works as expected. (int) accepts the 'floor' of the provided double value, so adding 0.5 makes it rounded up and down as expected.

0
source

All Articles