# WGS84-coordinate encoded as Integers

I want to store WGS84-coordinates in two integers for latitude and longitude instead of floats to get a higher precision than with floats.

Here's my code:

struct Coordinate
{
private int latitude;
private int longitude;

const double latMin = -90.0f;
const double latMax = 90.0f;
const double lngMin = -180.0f;
const double lngMax = 180.0f;

public Coordinate(double latitude, double longitude)
{
this.latitude = mapDoubleToInt(latitude, latMin, latMax);
this.longitude = mapDoubleToInt(longitude, lngMin, lngMax);
}

public double Latitude { get { return mapIntToDouble(latitude, latMin, latMax); } }
public double Longitude { get { return mapIntToDouble(longitude, lngMin, lngMax); } }

private static int mapDoubleToInt(double value, double min, double max)
{
return (int)(((long)int.MaxValue - int.MinValue) * (value - min) / (max - min) + int.MinValue);
}

private static double mapIntToDouble(int value, double min, double max)
{
return ((double)value - int.MinValue) / ((long)int.MaxValue - int.MinValue) * (max - min) + min;
}
}


I'm not sure if there is a better to convert the data. There are a lot of casts and arithmetic operations in it -- any way to do this more elegantly?

• You are using double not float. If you want more precision just use decimal. – paparazzo Jul 16 '17 at 9:00
• Decimals are horribly slow. :-( – user2033412 Jul 16 '17 at 16:13
• Decimal are not that much slow than double and you are going through a lot of effort here. You are going to need to cast a lot of the ints to decimal to not get integer math. – paparazzo Jul 16 '17 at 16:27
• But decimal takes 12 bytes! I can't afford that. Otherwise I would use doubles straight away, but I can't even afford those eight bytes. – user2033412 Jul 16 '17 at 17:19
• You should add that to the question – paparazzo Jul 16 '17 at 18:23

you can avoid stuffing everything in a one-liner:

private static int mapDoubleToInt(double value, double min, double max)
{
long intRange = 1L << 32; // ==((long)int.MaxValue - int.MinValue)
double inputRange = max - min;
return (int)(intRange * (value - min) / inputRange + int.MinValue);
}

private static double mapIntToDouble(int value, double min, double max)
{
long intRange = 1L << 32; // ==((long)int.MaxValue - int.MinValue)
double inputRange = max - min;
return inputRange * ((double)value - int.MinValue) / intRange + min;
}


After reordering the operations it's now clearer that they are opposites. Especially after extracting the range as variables.

• The recommendation on type suffixes are to use capitals so as not to confuse l with 1. Suggest using 1L instead. – Rick Davin Jul 13 '17 at 18:18
• Is (1L << 32) really what I want as range or is it ((1L << 32) - 1)? – user2033412 Jul 14 '17 at 9:52
• @user2033412 depends on whether max is inclusive or exclusive. – ratchet freak Jul 14 '17 at 9:55
• It's WGS84 coordinates -- I could make it exclusive by replacing +180° ⇒ −180°, you're right. – user2033412 Jul 14 '17 at 9:56