#c #types #floating-point #double #resolution
#c #типы #с плавающей запятой #двойное #разрешение
Вопрос:
Я храню много долгот и широт как doubles
, мне интересно, смогу ли я сохранить их как floats
.
Чтобы ответить на этот вопрос, мне нужно знать приблизительное разрешение числа с плавающей запятой одинарной точности, когда сохраненные значения являются долготами / широтами (от -180 до 180).
Комментарии:
1. Долгота колеблется от -180 до 180 градусов, а широта — от -90 до 90 градусов.
Ответ №1:
Ваш вопрос может иметь несколько интерпретаций.
Если это только для углов и для хранения на диске или на устройстве, я бы посоветовал вам сохранить ваши значения, используя совершенно другую технику: хранить как 32-битное целое число.
int encodedAngle = (int)(value * (0x7FFFFFFF / 180.0));
Чтобы восстановить его, сделайте наоборот.
double angle = (encodedAngle / (0x7FFFFFFF / 180.0));
Таким образом, у вас есть полное 31-битное разрешение для 180 градусов и 1 бит для знака.
Вы можете использовать этот способ также для сохранения ваших значений в ОЗУ, стоимость этого покрытия выше по сравнению с работой напрямую с удвоениями, но если вы хотите сохранить объем памяти низким, но разрешение высоким, это может сработать вполне хорошо. Стоимость не так высока, просто преобразование в / из целого числа из / в double и умножение, современные процессоры сделают это за очень короткое время, а поскольку доступная память меньше, если список содержит много значений, ваш код будет более дружественным к процессорукэш.
Ваше разрешение будет 180 / ((2^31) - 1) = 8.38190318 × 10^-8
в градусах, неплохо 🙂
Комментарии:
1. Он не может использовать целые числа без знака, потому что он должен представлять значения от -360 до 360. Хороший ответ.
2. Для lat / long -360, безусловно, является фиктивным требованием… В любом случае этот ответ правильный, и использование с плавающей запятой определенно неверно, если вы не хотите высокой точности вблизи Лондона и ужасного квантования в Тихом океане…
3. @SalvatorePreviti Спасибо за ваш ответ, это помогло уменьшить мой двоичный размер с 21 МБ до 17 МБ. Теперь его можно загрузить по воздуху!
4. широта фактически изменяется от -90 до 90. Итак, для широты вы можете просто заменить 90 на 180 в приведенных выше уравнениях кодирования / декодирования.
Ответ №2:
Разрешение, на которое вы можете рассчитывать при использовании поплавков с одинарной точностью, составляет около 360 / (2 ^ 23) или 4 * 10 ^ -5.
Точнее, самый большой поплавок с одинарной точностью, строго уступающий 360.
(который точно представим), составляет около 359.999969
. Для всего диапазона -360. .. 360
вы сможете представлять различия, по крайней мере, такие же малые, как разница между этими двумя числами.
Комментарии:
1. Фантастика, по моим расчетам, это максимум 5 метров для lon / lat, что для меня неприемлемо. Спасибо за помощь!
2. @Robert Когда вам нужно равномерное разрешение, форматы с плавающей запятой немного расточительны (хотя я бы признал, что они настолько удобны). С плавающими числами одинарной точности разрешение ограничено 23-битной мантиссой, когда у вас может быть 2 ^ 32 равномерно распределенных значения. Для двойной точности разрешение ограничено 52-битной мантиссой, где вы могли бы использовать все 64 бита для представления равномерно распределенных значений.
Ответ №3:
Зависит, но скорее нет.
32-разрядный float хранит 7 значащих цифр. Обычно этого слишком мало для хранения правильного разрешения долготы / широты. Например, openstreetmap.org использует шесть цифр после запятой, так что минимум восемь, максимум десять цифр.
Короче говоря, используйте float64.
Ответ №4:
Обычно значения с плавающей запятой составляют 4 байта (32 бита), а удвоения — вдвое больше. Однако точная точность, если вы выполняете вычисления, зависит от реализации (и аппаратного обеспечения). В некоторых системах все числа с плавающей запятой будут храниться как двойные, просто чтобы добавить путаницы.