Мне нравится идея использовать почти правильный метод для некоторых входных данных. Вот версия с более высоким «смещением». Кажется, код работает и проходит мой простой тестовый пример.
Просто замените ваш:
if(n < 410881L){...}
код на этот:
if (n < 11043908100L) {
//John Carmack hack, converted to Java.
// See: http://www.codemaestro.com/reviews/9
int i;
float x2, y;
x2 = n * 0.5F;
y = n;
i = Float.floatToRawIntBits(y);
//using the magic number from
//http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
//since it more accurate
i = 0x5f375a86 - (i >> 1);
y = Float.intBitsToFloat(i);
y = y * (1.5F - (x2 * y * y));
y = y * (1.5F - (x2 * y * y)); //Newton iteration, more accurate
sqrt = Math.round(1.0F / y);
} else {
//Carmack hack gives incorrect answer for n >= 11043908100.
sqrt = (long) Math.sqrt(n);
}
Если iPhone не предоставляет эту информацию напрямую, вам потребуется таблица поиска для перехода от языкового стандарта к единицам измерения по умолчанию. Затем вы должны разрешить пользователю переопределить это значение по умолчанию.
Вы можете спросить пользователя, предпочитают ли они мили или километры, в предпочтении или что-то в этом роде. Затем всякий раз, когда вы показываете расстояние, вы бы сказали.
В псевдокоде
function distance(meters) {
if (userPrefersKM) {
return meters / 1000 + " kilometers";
else if (userPrefersMiles) {
return meters / METERS_IN_A_MILE + " miles";
}
Где METERS_IN_A_MILE
будет около 1600, но вы должны посмотреть это вверх.