Оператор сдвига влево в C дает странный результат - PullRequest
1 голос
/ 10 мая 2019

У меня есть следующая программа:

int main()
{
    int64_t a = 241294423792285589;
    printf("a = %lld, a << 63 = %lld", a, a << 63);
    return 0;
}

Я ожидал, что a << 63 будет равно 0, но выводится:

a = 241294423792285589, a << 63 = -9223372036854775808

Почему это так?

Ответы [ 3 ]

5 голосов
/ 10 мая 2019

Если вы преобразуете эти целые числа в двоичный код дополнения со знаком 2, вы поймете, почему:

241294423792285589 в двоичном виде -

0000001101011001010000000000000000000000011010111111011110010101

Сдвиг влево на 63 точки приведет к тому, что самый правый 1 окажется в самой левой двоичной цифре:

1000000000000000000000000000000000000000000000000000000000000000

Который в двоичном коде дополнения 2 равен -9223372036854775808.

Вы можете найти двоичные <-> десятичные преобразователи онлайн (например, такой: https://www.rapidtables.com/convert/number/decimal-to-binary.html), который может помочь сделать это более ясным.

Или вы можете даже попробовать этот калькулятор битового сдвига: https://bit -calculator.com / bit-shift-calculator

4 голосов
/ 10 мая 2019

Ваше выражение сдвига имеет неопределенное поведение. Нет никакой ценности, которую вы могли бы осмысленно ожидать от этого сдвига.

В С поведение левого смещения E1 << E2 для подписи E1 описано в 6.5.7 / 4

Если E1 имеет тип со знаком и неотрицательное значение, и E1 × 2 E2 представимо в типе результата, то это результирующее значение; в противном случае поведение не определено.

0 голосов
/ 12 мая 2019

Проблема в том, что вы сдвинули влево нечетное число (число с установленным наименьшим значащим битом) на 63 позиции влево в 64-битном слове.Получаемое вами значение равно

0b1000_0000_0000_0000_...._0000

или

0x8000000000000000

, которое (в дополнение к двум) является числом, которое вы публикуете в своем вопросе.

В любом случае, сдвиг на 63 места 64-битное число со знаком - это неопределенное поведение, так что это означает, что вы можете получить все что угодно ... даже если это огромное отрицательное число.

...