2010-12-07 2 views
1

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

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

+0

Почему вы хотите сделать магию? Магия менее понятна. Кроме того, предполагая, что вы имели в виду «-1 в случае отрицательного числа» (потому что ваш вопрос, как сказано в настоящее время, говорит -1 и 1 для положительного числа), если ваши номера колеблются от 0 до 254, как они могут быть когда-либо отрицательные? – 2010-12-07 23:13:21

+0

Я не могу понять ваш вопрос! – AraK 2010-12-07 23:13:57

+0

Что такое тип данных аргумента? – tmiddlet 2010-12-07 23:23:56

ответ

5

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

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

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

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

1

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

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

2

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

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

1

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

Смотрите также: 2's Complement

0

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

1

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

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; 
}; 

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

2

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

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

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

3

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

return (val > 0) - (val < 0); 
Смежные вопросы