It’s the other way around. BigDecimal
is telling you the truth. 0.26579999923706055 is closer to the value that your float
has got all the time, both before and after rounding. A float
being a binary rather than a decimal number cannot hold 0.2658 precisely. Actually 0.265799999237060546875 is as close as we can get.
When you print the float, you don’t get the full value. Some rounding occurs, so in spite of the float
having the aforementioned value, you only see 0.2658
.
When you create a BigDecimal
from the float
, you are really first converting to a double
(because this is what BigDecimal.valueOf()
accepts). The double
has the same value as the float
, but would print as 0.26579999923706055, which is also the value that your BigDecimal
gets.
If you want a BigDecimal
having the printed value of the float
rather than the exact value in it or something close, the following may work:
BigDecimal bd = new BigDecimal(String.valueOf(roundedNumber));
System.out.println(bd);
Output:
0.2658
You may get surprises with other values, though, since a float
hasn’t got that great of a precision.
EDIT: you were effectively converting float
-> double
-> String
-> BigDecimal
.
These insightful comments by Dawood ibn Kareem got me researching a bit:
Actually 0.265799999237060546875.
Well, 0.26579999923706055
is the value returned by calling
toString
on the double
value. That's not the same as the number
actually represented by that double
. That's why
BigDecimal.valueOf(double)
doesn't in general return the same value
as new BigDecimal(double)
. It's really important to understand the
difference if you're going to be working with floating point values
and with BigDecimal
.
So what really happened:
- Your
float
internally had the value of 0.265799999237060546875 both before and after rounding.
- When you are passing your
float
to BigDecimal.valueOf(double)
, you are effectively converting float
-> double
-> String
-> BigDecimal
.
- The
double
has the same value as the float
, 0.265799999237060546875.
- The conversion to
String
rounds a little bit to "0.26579999923706055"
.
- So your
BigDecimal
gets the value of 0.26579999923706055, the value you saw and asked about.
From the documentation of BigDecimal.valueOf(double)
:
Translates a double
into a BigDecimal
, using the double
's
canonical string representation provided by the
Double.toString(double)
method.
Links