2013-03-06 2 views
6

Этого код печатает B2продвижения Integer - какие шаги

short a=-5; 
unsigned short b=-5u; 
if(a==b) 
    printf("A1"); 
else 
    printf("B2"); 

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

+0

какой компилятор вы используете? – 2013-03-06 19:06:46

+0

[this] (http://en.cppreference.com/w/cpp/language/implicit_cast) может быть полезным. – juanchopanza

+0

Целое продвижение происходит только в выражении 'a == b' - это все, о чем вы спрашиваете? –

ответ

8

Давайте пройдемся по коду:

short a = -5; 

а = -5, которая вписывается в короткий. До сих пор так легко.

unsigned short b = -5u; 

-5u средства применять унарный - оператора к постоянному 5U. 5u is (unsigned int) 5, а унарный - не продвигает рекламу, поэтому вы получаете 4294967291, что составляет 2^32-5. (Обновление: я ошибся в своем первоначальном ответе, см. Тестовый скрипт, который показывает, что эта версия верна здесь http://codepad.org/hjooaQFW)

Теперь, когда он помещается в b, он усекается беззнаковым коротким (обычно 2 байта) , поэтому b = 65531, что составляет 2^16-5.

if(a == b) 

В этой строке a и b повышаются до значений, чтобы сравнение могло происходить правильно. Если бы они были повышены до шорт, b потенциально обернулся бы. Если бы они были переведены на беззнаковые шорты, они потенциально обернутся.

Это как сказать if((int) a == (int) b). И a = -5, поэтому (int) a = -5 и b = 65531, поэтому (int) b = 65531, потому что ints больше шорт.

+0

Я бы не сказал, что '-5u' не имеет смысла - он хорошо определен стандартом. –

+3

Ум, '-5u' отлично разбирается. Он применяет '-' к целочисленной константе' 5u'. –

+0

Вы попали в точку, в которой меня интересует: поэтому BEFORE -5 хранится в короткой переменной «a» ... ее постоянное значение рассматривается как целое число, верно? Я очень заинтересован в этом вопросе –

3
a == b 

a и b оба повышен до int в приведенном выше выражении.

unsigned short b=-5u; 

В этой декларации -5U преобразуется в unsigned short средствами целочисленного преобразования (С99, 6.3.1.3p2 применяется здесь) и становится большим значением.

(С99, 6.3.1.3p2) «В противном случае, если новый тип без знака, значение преобразуется путем многократного сложения или вычитания один больше, чем максимальное значение, которое может быть представлено в новом типе, пока значение находится в диапазоне нового типа ».

b значение, то (unsigned short) ((unsigned int) USHRT_MAX + 1 -5) который является (unsigned short) 65531, если USHRT_MAX является (unsigned short) 65535.

Так что у вас есть:

(short) -5 == (unsigned short) 65531

что эквивалентно после целого продвижения обоих операндов:

-5 == 65531

что эквивалентно 0.

+0

re «В системе дополнений двух», ну это так, независимо от знакового целочисленного представления, потому что священный стандарт требует, чтобы он был двоичным, а потому, что 5 намного меньше, чем минимальный требуемый диапазон, и потому что стандарт требует, чтобы арифметика без знака была по модулю 2^n, где n - число битов представления. Так, например, для 32-битного 'unsigned' и 16-битного' unsigned short' выражение '-5u' само по себе дает значение 2^32-5, а затем это значение по модулю 2^16 обязательно 2^16- 5. снова, независимо от знакового целочисленного представления. –

+0

@ Cheersandhth.-Alf Согласитесь, я удалил это предложение непосредственно перед вашим комментарием. Я начал с * на двухкомпонентной системе *, потому что сначала хотел добавить информацию об изменении представления (нет). – ouah

0

short к unsigned short является преобразование (таким образом, имея ранг преобразования)

short к int это продвижение (таким образом, имея продвижение ранг)

Сниженные являются предпочтительными по сравнению конверсии из-за рейтинга. Акции проводятся во время арифметических и других операций. Конверсии возникают при простом хранении одного интегрального типа внутри другого. Арифметические операции могут вызывать конверсии, а также рекламные акции, чтобы объединить типы. В качестве другого примера:

unsigned int u = 2; 
int i = 2; 
u + i; 

i преобразуется (не раскручен), чтобы unsigned.

Ваше значение преобразуется в большее значение, потому что оно обертывается из-за unsigned. Затем они повышаются до int. Таким образом a != b из-за этого.

Смежные вопросы