Подтвердить что ты не робот

Почему в Android API так много плавающих?

Тип с плавающей запятой по умолчанию в Java - это double. Если вы произвольно скопируете константу типа 2.5 в свою программу, Java автоматически сделает ее двойной. Когда вы выполняете операцию над поплавками или ints, которые потенциально могут извлечь выгоду из большей точности, тип "повышается" до double.

Но в Android API все кажется плавающим из томов звука в прямоугольные координаты. В большинстве рисунков используется структура, называемая RectF; F - для поплавка. Это действительно боль для программистов, которые бросают продвинутые двойники обратно на (float) довольно часто. Разве мы не все согласны с тем, что Java-код довольно грязный и достаточно подробный, как есть?

Обычно математические сопроцессоры и ускорители предпочитают двойную работу на Java, потому что она соответствует одному из внутренних типов. Есть ли что-то в Android Dalvik VM, которое почему-то предпочитает поплавки? Или все поплавки являются результатом искажений в дизайне API?

4b9b3361

Ответ 1

В зависимости от ЦП не будет модуля с плавающей точкой (FPU). Поэтому он должен эмулировать FPU в программном обеспечении. это быстрее для Float, чем для Double. Или, если у устройства есть FPU, он, вероятно, также будет быстрее с Floats.

Ответ 2

На устройствах без FPU операторы с плавающей запятой с одинарной точностью намного быстрее, чем эквиваленты с двойной точностью. Из-за этого инфраструктура Android предоставляет класс FloatMath, который реплицирует некоторые функции java.lang.Math, но с аргументами float вместо double.

На последних устройствах Android с FPU время, требуемое для операций с одиночной и двойной точностью, примерно одинаковое и значительно быстрее, чем реализация программного обеспечения. (Страница "Проектирование для производительности" была написана для G1, и ее необходимо обновить, чтобы отразить различные изменения.)

Кстати, запись "2.5f" или "(float) 2.5" не имеет значения. В любом случае, javac знает, что вам нужна константа float с одной точностью и то, что она генерирует. Вы можете проверить это, написав пример программы и проанализировав байткод.

Ответ 3

Для показателей, которым не нужно слишком много значимых цифр (например, смещения экрана), было бы неэффективно использовать double вместо float s. Максимизация эффективности в отношении потребления памяти жизненно важна на мобильных устройствах, где почти каждый ресурс стоит на высоком уровне. И при работе с объектами, такими как Rect s &mdash, которые потенциально могут быть выделены тысячами, очевидно, важно сократить лишние биты.

Я уверен, что есть и другие причины: -)

Ответ 4

Weird. Проектирование производительности в руководстве, по-видимому, говорит: "... Обычная практика для настольных систем - свободно использовать плавающие точки... поэтому все операции с" плавающей "и" двойной "выполняются в программном обеспечении.... http://developer.android.com/guide/practices/design/performance.html#avoidfloat

Это может иметь смысл: "... Инструкции не могут быть ограничены конкретным типом. Например, инструкции, которые перемещают 32-битные значения регистра без интерпретации, не должны указывать, перемещают ли они ints или плавают....." на http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html

Ответ 5

Я думаю, что Роман прав, что причина, скорее всего, в основном предназначена для сокращения использования памяти. Считайте, что, когда предельная точность не важна, вы уменьшите вдвое память, необходимую для числовых переменных.

Помните, что нет необходимости использовать кастинг. Просто добавьте F в свой литерал (так 2.5 станет 2.5f). Я не знаю, достаточно ли укомплектован компилятор для выполнения следующей подстановки для вас, но если нет, это также сделает ваш код более эффективным.

Рассмотрим

float x = (float) 2.5;

и

float x = 2.5f;

В первом случае во время выполнения программа сохраняет двойной, а затем выполняет операцию литья, прежде чем сохранять полученное значение float. Во втором случае компилятор распознает значение как float, поэтому во время выполнения вы избегаете как сохранения двойника (хотя бы временно это может быть), так и избегания операции литья (поскольку она уже хранится как float).