2

i am trying to calculate the distance between two points and using the acos() function in process...but i am not getting a precise result..in case the distance is small

float distance_between(dest& point1,dest point2) {
float EARTH_RADIUS = 6371.0;//in km
float point1_lat_in_radians  =  point1.lat*(PI/180);
float point2_lat_in_radians  = point2.lat*(PI/180);
float point1_long_in_radians  = point1.lon*(PI/180);
float point2_long_in_radians  = point2.lon*(PI/180);

float res =  acos( sin( point1_lat_in_radians ) * sin( point2_lat_in_radians ) + cos( point1_lat_in_radians ) * cos( point2_lat_in_radians ) * cos( point2_long_in_radians - point1_long_in_radians) ) * EARTH_RADIUS;
cout<<res<<endl;
res = round(res*100)/100;
return res; 
}

i am checking the distance between the following co-ordinates 52.378281 4.900070 and 52.379141 4.880590
52.373634 4.890289 and 52.379141 4.880590 the result is 0 in both cases..i know the distance is small but is there a way to get precise distance like 0.xxx?

gsamaras
  • 71,951
  • 46
  • 188
  • 305
swarnava112
  • 421
  • 8
  • 19
  • Why is one parameter passed as a reference, and the other by copy? I sigegst `const dest&` for both. – Clifford Sep 05 '15 at 19:12
  • I am suspicious of your algorithm. The *great-circle distance* between your two examples is 1.326km and 0.8991km respectively, but when I tested your calculation with all `double` values, it yields 2.170km and 1.240km respectively. The unnecessary rounding introduces significant error, but that does not account for the results I obtained. – Clifford Sep 05 '15 at 19:23

1 Answers1

3

Use double instead of float to get more precision.

That way you are going to use this prototype:

double acos (double x);


A must read is the Difference between float and double question. From there we have:

  1. As the name implies, a double has 2x the precision of float.
  2. The C and C++ standards do not specify the representation of float, double and long double. It is possible that all three implemented as IEEE double-precision. Nevertheless, for most architectures (gcc, MSVC; x86, x64, ARM) float is indeed a IEEE single-precision floating point number (binary32), and double is a IEEE double-precision floating point number (binary64).
Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • Yo...it worked...thanks a lot for the help @gsamaras – swarnava112 Sep 05 '15 at 15:54
  • Glad to hear that. It's something that I had done wrong some years ago, that's why I upvoted. You can accept my answer if you want, so that other user see this as answered in the question feed. – gsamaras Sep 05 '15 at 15:58
  • @gsamaras: do you know if the standard specifies any precision by the way? as far as I know, it's entirely up to the quality of the implementation... – Matthieu M. Sep 05 '15 at 18:14
  • @MatthieuM. check my update, good comment, helped me improve my answer, thank you! – gsamaras Sep 05 '15 at 18:31
  • 1
    @gsamaras: I was thinking more about the precision of `acos` (I remember reading an article about the lack of precision of some arithmetic functions where the author complained about implementers cutting corners), but your addition is certainly worthwhile :) – Matthieu M. Sep 05 '15 at 18:34
  • @MatthieuM. I see. A quick search didn't give me any solid results. However I remember one professor telling us that people may choose the fast way (rather the correct one, i.e. when they have to round up for example, they will cut in order to be faster), which may lead to non-exact results. – gsamaras Sep 05 '15 at 18:36
  • @MatthieuM.: In a modern compiler math library I would be surprised if the the trig functions were not as good as they could be, especially on a target with hardware floating point. The issue here is purely that the input data has 8 significant digits, but `float` is good for only 6. – Clifford Sep 05 '15 at 18:49