Подтвердить что ты не робот

Интервью

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

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

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

4b9b3361

Ответ 1

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

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

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

С++ 03 делает поведение Undefined отсутствием соответствующего текста.

Ответ 2

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

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

Ответ 3

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

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

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

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

Ответ 4

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

Замените появление 0 на 1, поскольку вы собираетесь вычислять двоичный код отрицательного значения

Как рассчитать двоичные значения отрицательных чисел

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

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

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

1111 : F 

0000 : 0

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

FFFFFFF0

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

Ответ 5

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

-32768<<4

- это то же самое, что и

0x8000<<4

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

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

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

Ответ 6

Это поведение undefined.

$ 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

Ответ 7

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

Ответ 8

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