2010-11-24 3 views
38

меня попросили вывод следующего кода в моем интервью вчераИнтервью Вопрос

#include <stdio.h> 
int main(void){ 
     printf ("%x" ,-1<<4); 
} 

Я получил 2 минуты, чтобы сообщить ответ. Я ответил fffffff0. Результат интервью еще не объявлен. Я хочу знать, был ли мой ответ правильным?

+1

Разве это не зависит от представления целых чисел со знаком? – You 2010-11-24 17:46:26

+39

Ну, есть один способ узнать. Скомпилируйте и запустите код, глупый! – cdhowie 2010-11-24 17:46:52

+11

@cdhowie - если вы шутите, это смешно, но, вероятно, не полностью очевидно для OP. Если нет, то позоришься. – 2010-11-24 18:07:55

ответ

57

Технически левое смещение отрицательного целого вызывает Undefined Behavior. Это означает, что -1<<4 является UB. Я не знаю, почему они задали вам этот вопрос. Вероятно, они хотели проверить свою глубину знания стандартов C и C++.

C99 [6.5.7/4] говорит

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

C++ 03 делает это неопределенным поведением omitting the relevant text.

11

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

Истинный ответ заключается в том, что это реализация определена. Я не уверен на 100% сказать, что это неопределенное поведение из-за перегрузки, но я думаю, что это возможно. По крайней мере, хотя результат зависит от того, как представлены отрицательные числа и т. Д. Ни один из языков, на которые вы утверждали, заключается в определении того, каким будет выход.

8

На моей машине:

[email protected]:~$ cat > test.c 
#include <stdio.h> 
int main(void){ 
     printf ("%x" ,-1<<4); 
} 

[email protected]:~$ gcc -o test test.c && ./test 
fffffff0 

Однако результат будет зависеть от архитектуры и компилятора. Поэтому правильный ответ: «он мог бы выводить что угодно».

-5

Я только что написал код в текстовом файле, скомпилировал его, и ДА, ответ правильный.

3

Левое смещение отрицательного числа не определено для случая вообще, но мы должны понять, почему это неопределенное поведение (UB)? Имейте в виду, что наиболее значимый бит (MSb) является битом знака. Если этот бит равен 1, это число отрицательно. Если он равен нулю, число положительно. Это критическая информация теряется при первой левой смене. Например

-32768<<4 

это то же самое, как

0x8000<<4 

(предполагается, что на 16 разрядную машину для простоты)

В результате это, конечно, 0, которые на самом деле не имеет никакого смысла и, следовательно, UB.

В конкретном случае вопроса об интервью от ОП имеется только одно конкретное значение, которое мы имеем ... не общий случай. -1 (0xffffffff на 32-битной машине), сдвинутое влево 4 раза, даст 0xfffffff0, как первоначально думал ОП.

-2

Я запустил этот код на 3 разных компиляторах и ОС. Все дали мне тот же ответ, что и в вопросе. До тех пор, пока кто-то не придумает компилятор, на котором это действительно неопределенное поведение, я скажу, что ответ ПРАВИЛЬНО. Если это стабильно в 99,99% ситуаций, тогда есть больше шансов на стандартное изменение, чем компилятор прекратит его поддерживать.

7
Binary of 1 : 0000 0000 0000 0000 0000 0000 0000 00001 

Заменить вхождение 0 с 1, как вы собираетесь вычислить двоичный отрицательна не

How to calculate binary of negative numbers

Binary of -1 : 1111 1111 1111 1111 1111 1111 1111 11111 

Left shift 4 : 1111 1111 1111 1111 1111 1111 1111 0000 

Hex Представление результирующего левого сдвига будет

1111 : F 

0000 : 0 

поэтому рассчитанный выход будет:

FFFFFFF0 

Ваш ответ правильный.

1

Это неопределенное поведение.

$ cat undef.c 
#include <stdio.h> 
int main(void){ 
     printf ("%x" ,-1<<4); 
} 
$ clang -fsanitize=undefined undef.c 
$ ./a.out 
undef.c:3:24: runtime error: left shift of negative value -1 
fffffff0 
Смежные вопросы