Тест С++. Значит ли бит бит 1 всегда отрицательный?
Я просто сдавал тест на С++, и у меня был следующий вопрос:
В: Каков вывод следующей программы?
#include <iostream>
#include <stdint.h>
using namespace std;
int main() {
int a = 0;
for (int8_t i = 1; i > 0; i <<= 1)
a++;
cout << a;
return 0;
}
На выбор были выбраны
- 8
- 7
- Undefined Поведение
- Ошибка компиляции
"Правильный" ответ был равен 7. Если в ответах было "Реализованное исполнение", я бы выбрал это, поэтому я выбрал Undefined Behavior, который был скорее ближайшим. Я понимаю, что в sign-and-magnitute, 1 дополнение и 2 дополнения ответ будет равен 7. Но не позволяет ли стандарт С++ теоретически допускать любые другие представления чисел? Например, знак и величина, но 0 означает отрицательный?
Правильно ли я верю, что реальный правильный ответ на этот вопрос должен быть поведением, определяемым реализацией, а если нет, не могли бы вы объяснить, почему ответ равен 7 независимо от реализации?
Я прочитал комментарии к вопросу, и кажется, что изначально тип a
был char, что, видимо, вызвало множество жалоб на то, подписано ли char
или нет, так что тестовый набор изменил его на int8_t. В качестве бонусного вопроса, есть <stdint.h>
часть С++? O_O
Ответы
Ответ 1
Я бы сказал, что это undefined (а не реализация) по другой причине.
От 5.8: 3
Значение E1 << E2
- это E1, сдвинутые слева по E2 битовые позиции; освобожденные биты заполняются нулями. Если E1 имеет неподписанный тип, то результатом будет E1 × 2 E2 уменьшенный по модулю на один больше максимального значения, представляемого в типе результата. В противном случае, если E1 имеет подписанный тип и неотрицательное значение, а E1 × 2 E2 представляется в типе результата, то это результирующее значение; , поведение undefined.
Ответ 2
Если реализация предоставляет необязательный int8_t
, ответ должен быть правильным из проекта C99, который содержит ссылки на С++ 11 относительно stdint;
7.18.1.1 Точные целые типы
Имя typedef intN_t обозначает знаковый целочисленный тип с шириной N, без заполнения бит и представление двухкомпонентных дополнений. Таким образом, int8_t обозначает целое число со знаком тип с шириной ровно 8 бит.
Ответ 3
Поскольку сразу был дан ответ, я отвечу на вопрос о бонусе: <stdint.h>
- это заголовок C, который доступен на С++. Однако вместо этого используйте новый заголовок С++ <cstdint>
.