Inaccurate calculations using double and float [duplicate] - java

This question already has answers here:
Strange floating-point behaviour in a Java program [duplicate]
(4 answers)
Closed 8 years ago.
Why this piece of code is giving inaccurate results?
double a = 0.3 + 0.3 + 0.3;
System.out.println(a);
float b = 0.3f + 0.3f + 0.3f;
System.out.println(b);
Results are
0.8999999999999999
0.90000004

In Java, double values are IEEE floating point numbers. Unless they are a power of 2 (or sums of powers of 2, e.g. 1/8 + 1/4 = 3/8), they cannot be represented exactly, even if they have high precision. Some floating point operations will compound the round-off error present in these floating point numbers. In cases you've described above, the floating-point errors have become significant enough to show up in the output.

Related

Rounding a number to 2 decimal places fails [duplicate]

This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 5 years ago.
I have a nasty bug in an interest rate calculation: I have to round the answer to the nearest cent, but
interest = Math.round(interest * 100) / 100;
removes the entire decimal portion. interest is a double type. Why is this? The equivalent code works fine in C++.
Let's set aside the potentially greater issue of your using a binary floating point for a quantity that requires a precise decimal representation.
The Java bods broke with tradition and decided that Math.round(interest * 100) should return a long, rather than a double. (I imagine they did this since any double that is not an integer will be rounded to an integer that can fit into a long type). So the expression
Math.round(interest * 100) / 100
is evaluated in integer arithmetic, so any remainder is discarded. The clearest workaround in my opinion is to write
interest = Math.round(interest * 100) / 100.0;
which forces evaluation to take place in floating point.
Also note that the resultant underlying floating point value will, in general, have trailing non-zero digits past the 2nd decimal place even after this rounding has been applied: a double only gives you 15 decimal significant figures of precision.

Java double calculation problems [duplicate]

This question already has answers here:
Integer division: How do you produce a double?
(11 answers)
Closed 6 years ago.
I'm currently working on a Trafficsimulation which is based on a grid system. For some reason the line of code, which calculates how many tiles i have to add always returns 0. I have tried it without the variables but it still doesn't work.
double blocksToAdd = o.getVelocity()*((1000/Main.FPS)/1000);
Currently the velocity is equal to 1.0f and the Simulation runs at 10 FPS, so blocksToAdd should be 0.1, but it always returns 0.
Since Main.FPS is an int, 1000/Main.FPS is also an int, equal to 100. You then proceed to calculate 100/1000. Since this is an integer division, only the "whole" part is taken, giving 0.
Using floating point literals will cause Java to use floating point division, which should produce the correct result:
double blocksToAdd = o.getVelocity() * ((1000.0 /Main.FPS ) / 1000.0);
// Here --------------------------------------^--------------------^
Most likely due to integer division tuncating the fraction.
Replace the first 1000 with 1000.0 and all will be well. (The latter is a floating point double literal which causes the division to be computed in floating point.) There are other remedies but I find this one to be the clearest.

Why do floating-point numbers have roundoff errors? [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
I have been struggling to understand the concept of roundoff errors in Java with floating-point. While I understand that double is not supposed to be used for financial calculations, I don't understand why the 'd' variable does not come out to 0.0. How can I get this to print out the first println?
package zetcom;
public class floatingComparison {
public static void main(String[] args) {
double r = Math.sqrt(2);
double d = r * r - 2;
if (d == 0)
{
System.out.println("sqrt(2) squared minus 2 is 0");
}
else
{
System.out.println("sqrt(2) squared minus 2 is " + d);
}
}
}
Any explanation would be appreciated.
Short answer:
The square root of 2 requires an infinite number of digits -- that is, infinite precision. doubles have 52 bits of precision. That's a lot, but it's far, far short of infinite.
If you tried to represent 1/3 with two digits (0.33), you wouldn't be surprised at rounding errors, right? You'd multiply it by 3 and be not-at-all-surprised to get an answer of 0.99 instead of 1.0. It's the same thing exactly.
Digging a bit further...
What's a bit more un-intuitive is that numbers that can be represented with a infinite number of digits in base 10 might not be able to be represented by a finite number of digits in base 2 (which is what doubles and floats use). For instance, 1/10 is 0.1 in base 10, but it's 0.0001100110011... in base 2. So it will also be rounded off when you store it as a double, for the same reason as above: storing 1/10 in a finite number of digits in binary is as impossible as storing 1/3 in a finite number of digits in decimal.
Digging in even more...
And finally, you can look at it the other way around, too. While 1/3 is impossible to write in decimal with finite precision, it's just 0.1 in base 3.
Floating point numbers in virtually all languages are always approximate (bar powers of 2), because they cannot be accurately represented in binary. This is due to how computers process information: in bits.
For instance, how do you represent .3 in binary? You're always going to get a round off error if you try to achieve maximum precision with floating point numbers due to them having to be represented in binary.

Floating point number representation, Java example [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 9 years ago.
Could you please explain, why I got next result:
when I run this:
System.out.println((0.2 - 0.1));
I got: 0.1
when I run this:
System.out.println((0.3 - 0.2));
I got: 0.09999999999999998
I know that number "0.1" doesn't have finite representation in binary, but it doesn't explain the results above. Most likely this is not about particular language but about how digits are stored in computer.
Java uses IEEE floating point to represent double values. It is not a precise representation, and some calculations result in tiny errors that manifest themselves in this way.
I agree with Bohemian above (float and double is not precise) so you will get oddities like this
but there is a solution for your problem:
NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(1);
nf.format(0.3f - 0.2f);
This will produce 0.1.

Java - Double precision floating point [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to fix double precision issue in java
I have a small piece of code like this:
double number1 = 6;
double number2 = 5.99;
double result = number1 - number2;
However, the result == 0.009999999999999787 instead of 0.01
I know it is the issue of IEEE 754 standard, but I don't understand why. Could you please explain it for me?
This is because float point numbers cannot be exactly represented with in binary system with limited bits (not without precision loss)
See: http://en.wikipedia.org/wiki/Loss_of_significance
Because there is no .01 in floating point numbers. The fractional bits are expressed as 1/root 2 so you can get something like .0125 or what you have there but there is not .01 in floating point numbers. If you need exact precision use integers instead.

Categories