最近在项目开发过程中,遇到一些移位问题和有符号无符号转换时的表达问题,造成了种种的困惑。所以,个人抽出一点时间与之做了个彻底的了断。废话少说。切入正题.
来看一下代码:
int _tmain(int argc, _TCHAR* argv[])
{
char ch = 0x13;
int value = ch << 8;
value = ch << 16;
value = ch << 24;
value = ch << 32;
return 0;
}
你能说出每一步的value的值吗?
笔者之前一直认为,移位操作,左移就是将位左移,右补0;右移就是将位右移,左补零.(其中涉及算数移位与逻辑移位)。逻辑移位就是不考虑符号位,而算术移位需要考虑符号位.但是在将char左移32位时,预想的结果为0,但实际上是0x13.发生了循环移位,其并未丢掉移除的位进行补零操作。这与编译器有关吗?往达人指点.
总结几点:(1)移位操作 若不强制设定类型 默认为int 上例中会将ch转换为int
(2)移位过程中 若超出了int的范围 例如移位32为 则会发生循环移位 目前不确定是否与编译器有关
(3)有时根据需要需要考虑算术与逻辑移位操作
以上是移位 再看下面的负数表达问题
int _tmain(int argc, _TCHAR* argv[])
{
char ch = 0x13;
int value = ch << 8;
value = ch << 16
value = ch << 24;
value = ch << 32;
__int64 l_value = ch << 62;
__int64 l_value_0 = -0x4000000;
return 0;
}
其中 ch << 62位后 其值为0xc0000000 由于是按照int解析 所以其值 = -0x4000000 该值赋予__int64时 最高符号位为1 求反码后+1 最终得到0xffffffffc0000000;
l_value与l_value_0的值是相等的.