2016-09-18 3 views
0
int isNegative(int x) { 
    return ((unsigned) x)>> 31; 
} 

Я пишу функцию, которая принимает 32 бита и возвращает 1, если x < 0 и 0 в противном случае. Как преобразовать подписанный int в unsigned int без кастинга.преобразование из подписанного int в unsigned int без литья

+4

Непонятно, почему код не просто «возвращает x <0», так как он соответствует цели более высокого уровня «возвращает 1, если x <0 и 0 в противном случае». Конечно, это не отвечает нижним целям, которые я считаю немного неясными. – chux

+1

Если вы хотите, чтобы ваша функция взяла 32-битный тип данных, это «длинный», а не int. – Fredrik

+3

Зачем вам нужно конвертировать без кастинга? Это то, что отличает * для *. –

ответ

0

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

Предполагая, что int 32 бит, удалив результаты литья в -1 для отрицательных чисел и 0 для неотрицательных чисел. Хотя фактическое значение возврата отличается для неотрицательного случая, в булевом контексте оно будет работать так, как вы ожидаете.

+2

Деталь: «результаты в -1 для отрицательных чисел и 0 для неотрицательных» - это _very_ общее, но поведение, определенное реализацией. – chux

+0

Ответ является ограничительным, но DV является чрезмерным. – chux

0

Ваш вопрос, чтобы написать функцию, которая принимает 32 бита и возвращает 1 если x < 0

int isNegative(int x) { 
    return x < 0; 
} 

Это не будет работать независимо от того, каков размер int и не вызывает каких-либо преобразований типов. Полагаю, вы передумали эту проблему.

3

ОП имеет различные подразумеваемые вопросы

функция, которая принимает 32 бита и возвращает 1, если х < 0, и 0 в противном случае.

int isNegative(int x) { 
    return x < 0; 
} 
// or maybe return bool/_Bool 
bool isNegative(int x) { 
    return x < 0; 
} 
// or pedantically 
int isNegative(int_least32_t x) { 
    return x < 0; 
} 
// or pedantically and nearly universally portable, 
int isNegative(int32_t x) { 
    return x < 0; 
} 

преобразование из подписал INT беззнаковое междунар без литья (а)
Как преобразовать signed int к unsigned int без литья.

Просто присвоить значение

int i; 
unsigned u = i; 

Попытки использовать >> комбинированных этих два реализаций риски, определенное поведение и его следует избегать, если веские причины не дают.

ПРИМЕР Пример реализации, определяемый реализацией, - это распространение бит высокого порядка, когда целое число со знаком сдвигается вправо. C11§3.4.2 2

0

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

Таким образом, можно достичь конверсии (signed) int аргументов unsigned int просто объявив, что будет типом параметра:

int isNegative(unsigned x) { 
    return x >> 31; 
} 

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

int isNegative(int x) { 
    unsigned ux = x; 
    return x >> 31; 
} 

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

Конечно, я предпочитаю еще более простое семейство подходов, предложенное @chux.