Мне любопытно поведение побитового оператора C на характере.
#include <stdio.h>
int main()
{
int x = 108;
x = x<<1;
printf("%d\n", x);
char y = 108;
y = y<<1;
printf("%d", y);
//printf("%d", y<<1);
return 0;
}
Здесь, если я передам так, y = y<<1, на выходе будет -40, и когда я напечатаю это напрямую, например,
printf("%d", у<<1);
его выход был 216.
Как я могу смоделировать это?
y<<1
производит int
. Чтобы получить -40, вы неявно приводили его к char
. В вашем случае printf
вам нужно явно выполнить приведение: (char)(y<<1)
and I think the truncation from int back to char is technically undefined signed overflow
Не беспокойтесь, реализация определена.
@ShadowRanger, все верно, но это проблемы, которые относятся к коду, который OP попросил воспроизвести. Я показал, как реплицировать код, проблемы и все такое.
@ikegami: я не критиковал, просто добавил примечание в пользу ОП.
@KamilCuk: Отлично, просто непортативный, без носовых демонов. :-)
Да, я понял. Также в пользу ОП :)
Обратите внимание, что на самом деле нет операции <<
над char
типами — операнды <<
повышаются до (по крайней мере) int
типов, и результатом, аналогичным образом, является int
.
Итак, когда вы выполняете y = y << 1
, вы усекаете int
результат операции до (со знаком) char
, в результате чего старший бит (бит знака) остается установленным, поэтому он интерпретируется как отрицательное значение.
Однако, когда вы передаете y << 1
непосредственно в printf
, результирующее int
остается неизменным.
Примечание. Он может вести себя по-разному на другом компиляторе или с другими флагами компилятора;
char
имеет подписанность, определяемую реализацией, поэтому-40
подразумевает, что этоsigned
в этой реализации (и я думаю, что усечение отint
обратно доchar
является технически неопределенным переполнением со знаком, но не буду клясться в этом; большинство систем являются дополнением до двух и ведут себя так, как наблюдается) , но с таким же успехом это может быть216
в другой системе, где естьunsigned
. По сути, никогда не используйте простойchar
для математики, которая дает результаты за пределами диапазона [0, 128).