Dead Programmer
Dead Programmer

Reputation: 12575

Assign to Float from string with precision

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

Answers (4)

Peter
Peter

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

NPE
NPE

Reputation: 500247

Float doesn't have enough significant digits to represent your number. Try Double.

Upvotes: 0

T.J. Crowder
T.J. Crowder

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

Jon Skeet
Jon Skeet

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

Related Questions