Reputation: 12575
I have the following code, I want to assign a decimal value to float without losing precision.
String s1= "525.880005";
Float f = new Float(s1);
System.out.println(f);
Output: 5.88
Expected Output: 525.880005
Upvotes: 1
Views: 1675
Reputation: 48958
There's a real contradiction implied in the question :
Assign to float <--> wiht precision
525.880005 is jus the number in this float-domain that is closest to 525.88.
The reason that floating numbers cannot be mapped to all numbers is because of the mismatch between the decimal and the binary system for fractions.
Other types, such as decimal and money, use other, much more memory consuming, techniques to store the number (for example , in a string you can store any number, but of course this is not the most performant way to do math)
a simple example : 0.3 in my own binary system :
0.1b (inary) would be 0.5 d (ecimal) so too much...
0.01b --> 0.25d (1/4 too little)
0.011 --> 0.375 (1/4 + 1/8 too much)
0.0101 --> 0.3125 (1/4 + 1/16 still too much)
...
0.010011 --> 1/4 +1/32 + 1/64 = 0.296875
Suppose my system has 6 bits to represent the fraction, 0.296875 would be the closest for this domain. The right number cannot be reached due to the decimal/binary system.
For examples see also : Floating point inaccuracy examples
And an excellent elaborate explenation of your problems is to be found here: http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
Another note : it is really about mismatch, not about 'quality' of systems : in decimal notation for example, you cannot represent 1/3 100% accurate, while this would be perfectly possible in other systems.
Upvotes: 2
Reputation: 500247
Float
doesn't have enough significant digits to represent your number. Try Double
.
Upvotes: 0
Reputation: 1074138
The float
type cannot hold every possible value (nor can double
). If you're assigning from a string, you may prefer BigDecimal
as BigDecimal
can precisely hold anything that you can reasonably represent with a string.
Note that BigDecimal
also cannot hold every possible value (it can't precisely represent 1/3rd, for instance, for the same reason we can't write 1/3rd precisely in our decimal notation system — it would never end). But again, if your source is a string value, BigDecimal
will more closely align with your possible values than will float
or double
. Of course, there's a cost. float
and double
are designed to be very fast in computation; BigDecimal
is designed to be very precise with decimal values, at the expense of speed.
Upvotes: 1
Reputation: 1500055
Float
only has 7-8 significant digits of precision. The "5" in your example is the 9th digit.
Even if it had enough precision, I don't know whether 525.880005 is exactly representable as a binary floating point number. Most decimal values aren't :)
You should use BigDecimal
if the exact decimal representation is important to you.
Upvotes: 5