0

I want to convert longitude and latitude that I get as a string from my database. The string is correct, and when i try to convert it into double, it is also correct. However when i am convert the double or the string value (i have tried both) into a float value, the last decimal gets round off.

The value of the string or double is 59.858139 The convertion to float is 59.85814

I've tried everything, and this is one desperate example :)

private float ConvertToFloat(double d)
{
    float f = 00.000000f;
    f = (float) d;
    return f;
}
hammerpath
  • 45
  • 9

3 Answers3

7

You are aware that doubles have more precision than floats and that floats round off, right? This is expected behaviour. There is no sense in casting a double to a float in this case.

Here's something to get you thinking in the right direction...

    Double.doubleToRawLongBits(long value);
    Float.intBitsToFloat(int bits);

Doubles can't fit into int and they have to fit into long. It's really twice the size, even mediating bits with strings won't do any good here.

Shark
  • 6,513
  • 3
  • 28
  • 50
  • Yes, but why does the float round off when i convert it from a string? Shouldn't it be the exact value as the string? The double convertion was just something i tried because the string convertion didn't work. – hammerpath Aug 09 '12 at 10:28
  • 1
    Float is 32 bits long, Double is 64 bits. The string is a string of characters. 32 bits aren't big enough to represent what you want (the string). – Shark Aug 09 '12 at 10:33
  • Take a look at this thread, it covers precision loss of floats http://stackoverflow.com/questions/11825719/precision-lost-in-float-value-using-java/11825865#11825865 – Shark Aug 09 '12 at 10:38
  • 1
    @user1587158: it is _impossible_ to store the exact value you want in a `float`, no matter what parsing or rounding algorithm you use. That's the point. – Louis Wasserman Aug 09 '12 at 11:33
3

1. float has only 24 bits of precision, which will be insufficient to hold the number of digits in your latitude and longitude.

2. The rounding off is due to the size of the number. So use double if you require floating point, or use BigDecimal

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
  • I'd recommend BigDecimals where doubles don't do the job, in a similar fashion like floats don't here. – Shark Aug 09 '12 at 10:35
1

We are starting with your decimal number 59.858139

Convert that number to binary: 111011.11011011101011101111111101011100011011000001000110100001000100...

I.e. the number is an infinite fraction in binary. It is not possible to represent it exactly. (In the same way that it is not possible to represent 1/3 exactly with decimal numbers)

Rewrite the number to some form of binary scientific notation:

10 ^ 101 * 1.1101111011011101011101111111101011100011011000001000110100001000100...

Remember that this is still in binary, so the 10 ^ 101 corresponds to 2 ^ 5 in decimal notation.

Now... A float value can store 23 bits in the mantissa. If we round it up using "round to nearest" rounding mode, we get:

10 ^ 101 * 1.11011110110111010111100

Which is equal to:

111011.110110111010111100

That is all the precision that can fit into the float data type. Now convert that back to decimal:

59.8581390380859375

Seems pretty close to 59.858139 actually... But that is just luck. What happens if we convert the second closest float value to binary instead?

111011.110110111010111011 = 59.858135223388671875

So basically the resolution is approximately 0.000004.

So all we can really know from the float value is that the number is something like: 59.858139 ± 0.000002

It could just as well be 59.858137 or 59.858141.

Since the last digit is rather uncertain, I am guessing that the printing code is smart enough to understand that the last digit falls outside the precision of a float value, and hence, the value is rounded to 59.85814.


By the way, if you (like me are) are too lazy to convert between binary and decimal fractions by hand, you can use this converter. If you want to read more about the details of the floating point system, the wikipedia page for floating point representation is a great resource.

Alderath
  • 3,761
  • 1
  • 25
  • 43
  • Please use IEEE754 instead of binary mathematics ;) also, there's this http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Shark Aug 09 '12 at 13:04
  • @Shark the purpose was not to convert the decimal value to floating point representation. His program already does that. The point was to illustrate that the number is an infinite fraction in binary, and hence impossible to represent exactly, no matter what precision is used. – Alderath Aug 09 '12 at 13:14