如何解释位右移两种不同的结果?

时间:2017-04-13 10:18:59

标签: c bitwise-operators

我得到两个不同的结果,我很困惑,代码是:

int main () 
{
    int i = 0xcffffff3;
    printf("%x\n", 0xcffffff3>>2);
    printf("%x\n", i>>2);

    return 0;
}

结果是:

  

33fffffc
      f3fffffc

2 个答案:

答案 0 :(得分:3)

0xcffffff3 >> 2中,unsignedi >> 2 i signed时,这两个值都被视为1

因此,算术移位在签名情况下前置(unsigned)i >> 2位,因为在移位之前该数字为负。

如果您想要与常量相同的结果,请使用unsigned i = 0xcffffff3;或定义pd.crosstab(df['c_name'], df['p_name']).stack().reset_index(name='Freq')

答案 1 :(得分:3)

这一切都归结为0xcffffff3。这是一个十六进制整数常量。常数的类型取决于其大小。我们来参考C11 § 6.4.4.1 ¶ 5

  

整数常量的类型是相应列表中可以表示其值的第一个。

     

八进制或十六进制常量 - int,unsigned int,long int,unsigned long int,long long int,unsigned long long int

假设您的系统上有32位整数表示。 0xcffffff3的类型是unsigned int。

现在,当你执行int i = 0xcffffff3;时,无符号常量将转换为有符号整数。此转换产生负值。

最后,当右移时,它具有由C11 §6.5.7 ¶5

定义的语义
  

E1>的结果> E2是E1右移E2位位置。如果E1具有无符号类型或者E1具有有符号类型和非负值,则结果的值是E1 / 2 E2 的商的整数部分。如果E1具有有符号类型和负值,则结果值是实现定义的。

移动无符号常量会产生0xcffffff3/4并且移位i会产生实现定义的值(在这种情况下为负整数)。