0

I need to get CLLocation object with latitude and longitude having precision only to 6 points. But when I create a CLLocation object from floating point values, I get CLLocation object with latitude and longitude with greater precision (say up to 10 points).

What I have is latitude = 10.268408, longitude = 76.353965

I use the following code to create CLLocation object with the above coordinates.

CLLocation *createdLocation = [[CLLocation alloc]initWithLatitude:latitude
                                                longitude:longitude];

After creating the above object I printed the value for createdLocation.coordinate. What I get is (latitude = 10.268408101671659, longitude = 76.353965649742264)

So how and why iOS automatically complete the precision to 15 from my 6 point precision?

Update

Now I inserted the latitude and longitude to core data db. Then I fetch the lat-long from DB and then created a CLLocation object. Now the precision is as I wanted(shown below)

latitude = 10.268408, longitude = 76.353965

What difference occured when I wrote to DB? Why is it not working with float variables of 6 point precision?

krishnanunni
  • 510
  • 7
  • 16
  • 1
    the CLLocations stores the values as doubles. since float as well as double aren't "continuous" as you we are used from numbers, they store "discreet steps". So my guess is that you see the next matching doubles to your floats. You may see this for example regarding float/double http://stackoverflow.com/questions/5098558/float-vs-double-precision – Volker Jan 05 '15 at 13:33

1 Answers1

3

As Volker says, the location manager uses doubles to store the coordinates for lat/longs.

Computers use IEEE binary floating point, which does not really have a given number of decimal places.

If you use code like this:

double a = .1;
NSLog(@"a = %.9f", a);

You will see a value like

.099999998 

That is because most decimal fractions don't have an exact equivalent in binary notation. (Just like 1/3 does not have an exact equivalent in decimal, it comes out as .3333333333333333333333 {repeating})

If you want to convert your values to a decimal value with a fixed number of decimal places you can convert it to a string, or perhaps an NSDecimalNumber.

(NSDecimalNumber is a different way of representing decimal values as an exact set of decimal digits, with no binary-to-decimal conversion problems.)

To convert to a string, you'd do something like this:

CLLocationCoordinate2D aCoordinate;
NSString *latString = [NSString stringWithFormat: @"%.6f", aCoordinate.latitude);

I haven't used NSDecimalNumber enough to type out an example of using it without doing some research. I leave that as an exercise for you.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 2
    Also note that despite all the bits in the result, your actual precision is never that good. Standing outside our office I can rarely get a result better than +/- 70 meters. See http://gis.stackexchange.com/questions/8650/how-to-measure-the-accuracy-of-latitude-and-longitude/8674#8674 for a great discussion of GPS precision and accuracy. – ahwulf Jan 05 '15 at 14:11
  • Good point. The GPS's in iOS devices are not great. The best I usually get is +/- 15 meters. – Duncan C Jan 05 '15 at 14:51
  • Retrieving coordinates with required precision can be done as above. But my problem is different. When I set coordinates for CLLocation using less precision float values, I eventually get coordinates with higher precision. – krishnanunni Jan 06 '15 at 04:54
  • @krishnanunni and as answered you can't avoid that due to how numbers are stored - you may want to explain why it is a problem or why you don't use doubles in the beginning avoiding this conversion and precision "error" – Volker Jan 06 '15 at 11:23
  • @Volker I am able to create CLLocation object as I wanted. But I am not satisfied with that. How I did is, I wrote the latitude and longitude to database using CoreData. Then I fetched the same data. After that, when I created the CLLocation object, it gave me the coordinates with less precision. Now it works for me. But I just want to know why this happen. That is, why it works when I write and fetch from db? – krishnanunni Jan 06 '15 at 11:47
  • 1
    Binary floating point numbers do not have any concept of decimal precision, just like fractions don't have any decimal precision. What is the decimal precision of 1/3? It doesn't make sense. Neither does a decimal (base 10) precision of a binary (base 2) floating point number. If you want to save a number with a specific number of decimal digits, either save it as a string, or as an NSDecimalNumber. – Duncan C Jan 06 '15 at 13:52