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.
Related
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.
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
double test = 1029 / 9.8; // = 104.99999...
int inttest1 = (int) test; // 104
int inttest2 = (int)Math.floor(test); // 104
double testtt = 9.8 * 105; // 1029.0
1029 / 9.8 equals 105
but Java returns 104.9999...
More serious problem is integer casing result is 104, not 105
Why this happens and how can I avoid this result?
There are an infinite number of numbers, even in the limited range represented by Java. That's because mathematically, if you give me any two distinct numbers, I can average them to get a number between them. No matter how close they are.
And there are only a limited number of bits available to represent those numbers.
Hence, something has to give. What gives is the precision of the numbers. Not all numbers can be represented exactly, so some (the vast majority actually) are approximations.
For example, 0.1 cannot be represented exactly with IEEE754 encoding, even with a billion bits available to you.
See this answer for more information on the inherent imprecision of limited-storage floating point numbers.
Casting to an int implicitly drops any decimal. No need to call Math.floor() (assuming positive numbers)
To avoid this behavior use BigDecimal;
http://docs.oracle.com/javase/7/docs/api/java/math/BigDecimal.html
Standard floating point variables are in binary floating point. Many decimal floating point values (which are the ones you type in your code) have no exact representation in binary floating point. So it isn't doing the calculation with the exact numbers you entered but with some values very close to it. You can use Math.round to round the result to the precision you need and most likely the small error will disappear.
If you really need exact decimal calculation use BigDecimal but note that it is much slower.
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.
This question already has answers here:
How to round a number to n decimal places in Java
(39 answers)
Closed 9 years ago.
I just wanted to ask a quick question regarding the Math.round method. I'm trying to compute the division of two ints into a double. The equation looks like this: 199/39. When I do this it returns 5.0 as the answer. I know the answer should be 5.1 with some more decimals. I have been told to use the Math.round method to round it to the nearest tenth, but I have no idea how to accomplish this. Should I change that double variable to a int and make it int/int=int? I'm not sure how Math.round even works to get 5.1 as I've read it only rounds to the nearest integer not decimal point. Any help would be fantastic.
P.S This is homework, but I ask only because I can't find any information in my notes, slides, or book on how to use Math.round.
You don't need Math.round() to get a resultant decimal value. If you divide an int by an int, you will get an int. if you want a decimal, then cast double to one of the input values. Then you will get a double as a result.
(double) 199 / 39
199.0 / 39
// both return
5.102564102564102
I know the answer should be 5.1 with some more decimals.
Not with integer division it shouldn't. 5 is correct.
If you want a floating-point answer, you need to provide at least one floating-point operand, e.g. 199/39.0.
You can then format that for printing with as many or few decimal places you like, with System.printf() or DecimalFormat.
You can't round the floating-point value itself to decimal places, because it doesn't have decimal places, it has binary places.
See this question for a full discussion, especially my answer there.
Your specific answer:
roundedNumber = (double)Math.round(unRoundedNumber * 10) / 10;
In general, the equation is:
roundedNumber =
(double)Math.round(unRoundedNumber * Math.pow(10, digitsToRoundTo))
/ Math.pow(10, digitsToRoundTo);
Thanks for all the help. After reading your posts and looking at it some more I ended up doing ratio=((double)199/39) and then going
ratio=(double)Math.round(ratio*10)/10. Doing that got me the 5.1 i was looking for.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Precision of Floating Point
double a=0.000001,b=50000;
b=a*b;
System.out.println("double:"+b); // -> double:0.049999999999999996
float a=0.000001f,b=50000;
b=a*b;
System.out.println("float"+b); // -> float0.05
I have used double in most part of my code and today I found this problem.
How should I handle this?
Context:
double []refValues= {100,75,50,25,15,5,1};
double bInMilliGram=b*1000;
double pickedVal=0;
for(double ref:refValues)
if(ref<=bInMilliGram) {
pickedVal=ref;
break;
}
System.out.println("bInMilliGram:"+bInMilliGram+", pickedVal:"+pickedVal);
o/p: -> bInMilliGram:49.99999999999999, pickedVal:25.0
If you need arbitrarily good precision, use the java.math.BigDecimal class.
It is not a problem. It is how double works. You do not have to handle it and care about it. The precision of double is enough. Think, the difference between you number and the expected result is in the 19 position after decimal point.
The only conclusion from this fact is never try to compare floating point values using == - the results may be confusing.