Можно ли этого достичь, используя какое-то немного магии? - PullRequest
1 голос
/ 08 декабря 2010

Если есть функция, которая возвращает отрицательное число, 0 или положительное число.Вместо этого я хочу вернуть -1 в случае положительного числа, 0 в случае 0 и +1 в случае положительного числа.

Могу ли я добиться чего-то подобного, используя какую-то битовую игру илия должен делать обычные сравнения?

Ответы [ 8 ]

5 голосов
/ 08 декабря 2010

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

Вместо этого я предлагаю следующее "волшебство":

if (myvalue > 0)
   return 1;
else if (myvalue < 0)
   return -1;
else
   return 0;

Чисто, явно, переносимо и действительно очень быстро на большинстве компиляторов.Единственная правдоподобная оптимизация на уровне кода, которую я бы предложил, это сначала проверить (или потом) нулевое значение, если вы знаете, что этот случай встречается чаще.

3 голосов
/ 08 декабря 2010

Если вы ищете аккуратное выражение:

return (val > 0) - (val < 0);
2 голосов
/ 08 декабря 2010

Если вы готовы принять дополнение 2s, то сдвиг вправо со знаком типа является арифметическим (ни одно из этих предположений не переносимо, но они применимы ко многим распространенным платформам), и вы действительно не готовыслишком умный вдвое:

int number;
const int shift = sizeof number * CHAR_BIT - 1;
return (number >> shift) - (-number >> shift);

Несколько предположений для чего-то довольно загадочного, и нет никакой гарантии, что это действительно быстрее на любой конкретной платформе.

2 голосов
/ 08 декабря 2010

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

Просто используйте оператор if-else, ваш код будет проще, и вы сможете перейти к более важному программированию (или игре на SO:)).

1 голос
/ 08 декабря 2010

Если я правильно понял вопрос:

static inline int sign(unsigned int n){
    int sign_bit = n >> (sizeof(int)*CHAR_BIT - 1); //sign_bit = n<0 will also do
    int is_zero = !n;
    return 1 - is_zero - sign_bit * 2;
};

Это не "сжато", чтобы показать логику.

1 голос
/ 08 декабря 2010

Если целые числа представлены с помощью дополнения до 2, то вам нужно только взглянуть на самый значимый бит.Если это 1, то это отрицательный, в противном случае это положительный или ноль.

См. Также: 2's Complement

1 голос
/ 08 декабря 2010

Я собираюсь предположить, что (а) вы имели в виду -1 для отрицательного числа и (б) диапазон был от -254 до + 254.

Отрицательный или положительный результат можно оценить, взглянув только наодин бит, но для проверки на ноль вам нужно будет проверить все биты, чтобы убедиться, что все они равны нулю, что побеждает цель использования «ярлыка» для манипулирования битами.

0 голосов
/ 08 декабря 2010

Не ищите причудливую битовую магию, просто разделите число на его величину, и вы получите знак.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...