double precision / TinyGPS++

If you store GPS coordinates as degrees*1000000 in a long integer, you can preserve the accuracy needed for global positioning. However, calculations using trigonometric functions are limited to single precision floating point on the Arduino.

It is possible to get around this in various ways. For example, you can calculate the distance and bearing between two (lat, long) points using the equirectangular approximation, which treats the Earth locally as a flat surface. This is good for points up to about 10 km distant, with precision and accuracy of better than 1 meter (better than GPS accuracy). See the code below for an excellent web site that describes the various approximations.

Example code:

// find the bearing and distance from point 1 to 2, using the equirectangular approximation
// lat and lon are degrees*1.0e6
// bearing is returned in degrees, distance in meters

// reference: http://www.movable-type.co.uk/scripts/latlong.html

double course_to(long lat1, long lon1, long lat2, long lon2, double* distance) {

double dlam,dphi,radius;

double deg2rad = 3.141592654/180.0;
double rad2deg = 180.0/3.141592654;
radius = 6371000.0; //approximate Earth radius in meters.

dphi = deg2rad*(lat1+lat2)*0.5e-6; //average latitude in radians
double cphi=cos(dphi);

dphi = deg2rad*(lat2-lat1)*1.0e-6; //differences in degrees
dlam = deg2rad*(lon2-lon1)*1.0e-6;

dlam *= cphi;  //correct for latitude

double bearing=rad2deg*atan2(dlam,dphi);
if(bearing<0) bearing=bearing+360.0;

*distance = radius * sqrt(dphi*dphi + dlam*dlam);

return bearing;
}