0

Status: Accepted best available answer with thanks after a week or so. Awaiting / inviting more answers with citations

This matter was complex. I am really thankful to ALL commentators and specially asciimo,Gabe Sechan,AlexWien. Please vote and/or answer further after due study.

Senario:

The Location.getLatitude() in android returns double which has low precision.

Api http://developer.android.com/reference/android/location/Location.html

Example:

Edit-2 begin

I just tried to send GPS cordinates by emulator and 111.422006 auto converted to 111.422004999999998 in Double dlongi = loc.getLongitude(); String longi = dlati.toString(); System.out.println(longi);

Edit-2 end

Edit-3 begin

I sent the coordinates by emulator (by GPS device in reality) as 111.422006, the android API received it as double value of 111.42004999999998

Edit-3 end

Too late for: BigDecimal class is too late for that as it already gives a d/Double.

Question: What if full accuracy is required.

What is a way to get it with good precision or in another form other than doubles?

Just thought to share and make others notice this too.

Requests: Please do not answer until you are sure of a good answer with citation . This would help the communtiy.

Edit:

Looks like Gps coordinats by normal GPS devices are them self not 100% FULLY accurate near to 3 meter for example but looks like doubles further decrease the accuracy. that was my question actually.

Masood Ahmad
  • 731
  • 4
  • 15
  • 38
  • 1
    Out of curiosity, why does this matter to you? – Karakuri May 31 '13 at 19:31
  • 1
    @Karakuri . :) GPS cordinates should be _exact_ as much as possible. and by chance my application cannot tolerate slight differences. Others might face the same situation, so I made a post – Masood Ahmad May 31 '13 at 19:32
  • 1
    If your app can't tolerate slight differences your app won't work. Different phones have different quality GPS recievers, some of which may not be accurate to even a meter. In addition, at any time the US military can (and does scramble the signal which can introduce inaccuracies of 20 meters. If you require such exact measurements your app is misdesigned. – Gabe Sechan May 31 '13 at 19:49
  • 1
    @GabeSechan I have added an EDIT for that senario – Masood Ahmad May 31 '13 at 20:09
  • The code for the Google API is here ( http://grepcode.com/snapshot/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/ ). I would recommend not recasting it yourself (as your code does above) before putting it into a String or BigDecimal. Your code must deal with the value provided by the Google contract, whether it is double or not. – ingyhere Jun 01 '13 at 03:26
  • The header for the C++ Android hardware library declares it as a double, too. https://github.com/android/platform_hardware_libhardware/blob/master/include/hardware/gps.h – ingyhere Jun 01 '13 at 03:32
  • please post full code, where do you assign 111.422006? i want ro see the full code from asignment to output. – AlexWien Jun 01 '13 at 11:32
  • 1
    full code no needed. see edit-3 for further clarification – Masood Ahmad Jun 01 '13 at 14:15
  • See Jakar's answer at http://stackoverflow.com/questions/3604849/where-to-save-android-gps-latitude-longitude-points . – ingyhere Jun 02 '13 at 19:44
  • @ingyhere jakars answer is wrong. and has little to do with this post – AlexWien Jun 02 '13 at 20:51

3 Answers3

2

Keep in mind that 3 meter latitudinal accuracy (for a very good consumer GPS receiver) only requires 5 decimal places.

asciimo
  • 240
  • 2
  • 11
  • Which does not change the problem. The limit with IEEE 754 floats is the fact that decimals are stored as (inverted) powers of 2. Try and encode 0.1 in a `double`: you can't. – fge May 31 '13 at 19:37
  • 1
    Yes it does solve the problem- the accuracy of a double is greater than the accuracy of GPS. The fact that it uses powers of 2 vs powers of 10 doesn't matter because the inaccuracy due to the difference is orders of magnitude less than the inaccuracy due to the system itself. Besides which, the actual world isn't digital its analog, meaning that any digital representation would have an accuracy loss- using a factor of 2 is no worse than a factor of 10. – Gabe Sechan May 31 '13 at 19:46
  • 1
    for asciimo and Gabe Sechan . You might be correct asciimo that GPS dont want a .xxxxxx 6 digit number. but if the cordinat is already rounded of or inaccurate, and implicitly GPS is not 100% accurate near to 3 meters. the accuracy will be further decreases. as i Stated Question: What if full accuracy is required. – Masood Ahmad May 31 '13 at 19:48
  • Indeed it does change the problem. Unless you are using military grade GPS there are limits of accuracy, which I believe are spec'd at 3 meters. – ingyhere May 31 '13 at 19:50
  • 1
    @GabeSechan it DOES NOT. What if you have to do computations? You'll botch the results because you use `double`. – fge May 31 '13 at 19:52
  • 1
    Masood- you don't understand floating point math or scientific accuracy. Your entire point is wrong because of this. There's no way to explain it more than we already have. You really, really need to study significant figures and understand what the real inaccuracy of a double is (hint: a double is accurate to e-308 with 53 binary digits (approximately 16 decimal digits). The GPS signal isn't accurate to more than 5 decimal digits). – Gabe Sechan May 31 '13 at 19:53
  • 1
    @fge That's only true if the underlieing data is decimal to begin with, like money. If the data is analog that doesn't apply. – Gabe Sechan May 31 '13 at 19:55
  • 1
    @fge nobody stops you from using [BigDecimal.valueOf(location.getLatitude())](http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html#BigDecimal(double)) if you feel it is important. – MaciejGórski May 31 '13 at 19:55
  • 1
    I just made an Edit: Looks like Gps coordinats by GPS devices are them self not 100% FULLY accurate near to 1 meter for example but looks like doubles further decrease the accuracy. that was my question actually. – Masood Ahmad May 31 '13 at 19:57
  • @MaciejGórski I already wrote. Too late for: BigDecimal class is too late for that as it already gives a d/Double.It just makes 111.422006 as 111.422004999999984420355758629739284515380859375 – Masood Ahmad May 31 '13 at 20:08
  • @Masood your problem is that you assume the answer is ever exactly 111.42006. It isn't. The actual answer is analog, so its infinite precision. That decimal answer is also inaccurate, to a roughly equal amount to the binary double. – Gabe Sechan May 31 '13 at 20:15
  • 1
    @GabeSechan thats what fge and iam saying. the double further makes 111.42006 further inacurate – Masood Ahmad May 31 '13 at 20:20
  • 1
    No, it doesn't. Its the exact opposite of what you're saying – Gabe Sechan May 31 '13 at 20:24
2

Your post shows that 111.422006 becomes to 111.422004999999, this is a difference of 0.00001 which cannot happen due double to Double casting.

This clearly shows that the reduction in precision is somewhere from emulator input and or internal GPS processing most probably for emulation purpose ( the emulator could interpolate when needed)

For sure it is not caused by type double.

For real GPS, even when android would cut off or round at the 6 digit after decimal points, this does not affect the positional accuarcy. gsp positions have an physical limit of 3m. when android would cut of that digit, the position can change by some centimeter. but that can safely be ignored, it is the position that the device tells, and that is the best known truth. you cannot improve. raising the number of digits does not improve GPS acuracy, you would need to have a better GpS antenna to improve acuracy.

Update:
Here the granularity of coordinates in meters related to used number of latitude / longitude digits:

This case is the worst case: the distance on equator from (0.0,0.0) to (0.0, lon2)

lon2= 0.1, meters = 11131.94558870502
lon2= 0.01, meters = 1113.194558870502
lon2= 0.0010, meters = 111.3194558870502
lon2= 1.0E-4, meters = 11.131945588705022
lon2= 1.0E-5, meters = 1.1131945588705023
lon2= 1.0E-6, meters = 0.11131945588705022

So 0.000001 is 11cm

You can calculate that by yourself, too:
Earth circumfence (approx) = 40.000 km
Divided by 360 degrees = 111.111 km = 111111 meters per degree (exactly it is 111319m)

1 digit  after comma: 0.1:   divide by  10=  11131.9 m  
2 digits after comma: 0.01:  divide by 100=  1113.19m  

and so on, look at the table above.

If you want the result more official: look at the link which asciimo has posted:

Coordinates in Decimal degrees

asciimo
  • 240
  • 2
  • 11
AlexWien
  • 28,470
  • 6
  • 53
  • 83
  • I agree to most extend with you. Can you give citation that how much accuracy depends (in meters) on the last decimal (in 6 decimals). E.g if its 111.123459 . if 9 some how converts to 1. how much distance would it had been misrepresented? – Masood Ahmad Jun 06 '13 at 19:14
  • Yes i can, one moment please – AlexWien Jun 06 '13 at 19:23
  • @MasoodAhmad 9 to 1 is 8 * 11cm = 88cm on equator. (On all other places the error can be smaller) You can write a simple program and use the distance function: The Location class has a method distance(), just pass in the two coordinates to test and measure the distance: (111.123459, 0) and (111.123451, 0) which gives 89cm at my programm, which is the expected result. – AlexWien Jun 06 '13 at 19:52
  • @MasoodAhmad I updated my answer, according to your last comment. – AlexWien Jun 06 '13 at 20:08
  • nice. thanks. and I just upvoted to compensate the downvote (who ever did that downvote). Despite I invite any type of comments and discussions. – Masood Ahmad Jun 16 '13 at 12:58
0

Double precision is not the problem here. Try this:

System.out.println(111.422006);

The output will be:

111.422006

The input seems to be processed somehow, whyever... So it's possible, that with real GPS data, the precision is better then your test suggests, hopefully...

Torben Kohlmeier
  • 6,713
  • 1
  • 15
  • 15
  • 1
    I read that... But this could just be a problem with the GPS emulation, which would actually not be a problem at all. Maybe, the location is sent to the emulator as a float and then converted back to a double. Casting `111.422006` to float and back to double results in `111.42200469970703` which is quite close to the value you posted. So, again, maybe this does not happen with real GPS data. – Torben Kohlmeier Jun 01 '13 at 00:09
  • oh. do you have a citation on " the location is sent to the emulator as a float and then converted back to a double." ? – Masood Ahmad Jun 01 '13 at 00:50
  • No, this was just an assumption of myself. – Torben Kohlmeier Jun 01 '13 at 00:57
  • 1
    thanks for the nice effort but I need to be sure. See Request: section of my post – Masood Ahmad Jun 01 '13 at 01:41
  • Maybe not, but please watch those capital 'Double' values versus lowercase 'double' values. I'm not sure this example is relevant. – ingyhere Jun 01 '13 at 03:44
  • @MasoodAhmad you state in your post that you send the coordinate to the emulator! – AlexWien Jun 01 '13 at 11:38