Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Работа оператора сдвига на число бит, превышающее разрядность переменной

#python #c


Есть код на C:

unsigned long result = (18lu << 340lu);
printf("result = %lu\n", result);


Результат выполнения:

result = 0


Однако, код:

unsigned long a = 18;
unsigned long b = 340;
unsigned long result = (a << b);
printf("result = %lu\n", result);


Даёт результат:

result = 18874368


Попытка реализации данного кода на Python:

a = c_uint32(18)
b = c_uint32(340)
result = c_uint32(a.value << b.value)
print("result =", result)


Дала, соответственно:

result = c_ulong(0)


Поэтому и непосредственно вопрос: как работает сдвиг влево в C с переменными и как
можно реализовать тоже самое поведение в Python с сохранением размерности c_uint32,
а не стандартного целого?
    


Ответы

Ответ 1



В С++ большой сдвиг - UB (про С солидную ссылку не вижу) In any case, if the value of the right operand is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined. В ассемблере Intel сдвиг выполняется по модулю размера числа в битах (32, 64). Соответственно по аналогии в Python можно сделать result = c_uint32(a.value << (b.value % 32))

Ответ 2



Открываем cppreference: ... if the value of the right operand is negative or is greater or equal to the number of bits in the promoted left operand, the behavior is undefined. То есть при размере типа N бит, сдвигать можно только на 0 <= x < N бит, иначе вы получаете неопределенное поведение. как можно реализовать тоже самое поведение в Python Так как поведение не определено, ответ - никак.

Комментариев нет:

Отправить комментарий