Мне только что сообщили о решении, которое дает 0,1,2,3 результатов квадранта, упорядоченных правильно:
#define LONG_LONG_SIGN (sizeof(long long) * 8 - 1)
double dx = point.x - center.x;
double dy = point.y - center.y;
long long *pdx = (void *)&dx;
long long *pdy = (void *)&dy;
int quadrant = ((*pdy >> LONG_LONG_SIGN) & 3) ^ ((*pdx >> LONG_LONG_SIGN) & 1);
Это решение для координат x, y двойного типа.
Я провел некоторое тестирование производительности этого метода и метода с ветвлением, как в первоначальном вопросе: мои результаты таковы: метод ветвления всегда немного быстрее (в настоящее время у меня стабильное отношение 160/180) , поэтому я предпочитаю метод ветвления, а не метод с побитовыми операциями.
UPDATE
Если кому-то интересно, все три алгоритма были объединены в EKA-алгоритмы C / Objective-C-репозиторий как алгоритмы "декартовой выборки квадрантов":
- Оригинальный алгоритм ветвления
- Битовый алгоритм @ruslik из принятого ответа.
- Альтернатива побитовая, предложенная одним из моих коллег, которая немного медленнее второго алгоритма, но возвращает квадранты в правильном порядке.
Все алгоритмы оптимизированы для работы с точками двойного типа.
Тестирование производительности показало, что в целом первый алгоритм ветвления является победителем в Mac OS X, хотя на машине с Linux мы видели, что второй алгоритм работает немного быстрее, чем алгоритм ветвления.
Итак, общий вывод - придерживаться алгоритма ветвления, потому что побитовые версии не дают никакого увеличения производительности.