与不同的位长度进行AND运算

时间:2013-04-18 06:18:29

标签: c bitwise-operators

我有以下内容:

void calculate(unsigned long num1, unsigned long num2){
   int32_t invertednum2 = ~(num2);    // yields 4294967040
   printf("%d\n", invertednum2);      // yields 255

   // num1 is 3232236032
   int32_t combine = (int32_t) num1 & num2;
   printf("%d\n", combine);           // yields 0???
}

我正在尝试AND num1和num2,结果是:

   000000000000000011111111

我不确定我是否正确地使用两种不同的位长度或者是否应该进行转换。

任何帮助将不胜感激!

由于

2 个答案:

答案 0 :(得分:2)

您不能在C中使用AND不同的位长度,因为您不能在不同类型的操作数上应用任何二元运算符(shift除外)。如果编写操作数不同类型的代码,C编译器首先会在执行操作之前将它们转换为相同的类型(因此大小相同)。 C规范中有7页(第6.3节)专门介绍了这种情况的具体细节。

结果当你有:

int32_t combine = (int32_t) num1 & num2;

num1num2都是unsigned long,这是64位,会发生什么:

  1. 演员表会将num1截断为32位
  2. AND有不同的操作数类型(int32_t和uint64_t),因此int32_t将符号扩展为64位。
  3. 对这两个64位值执行AND
  4. 结果被截断回32位并存储在combine
  5. 现在,因为num1是3232236032(0xc0a80200),步骤1和2会将其转换为0xffffffffc0a80200,它将与num2进行AND运算,然后将丢弃那些前32位。

    相反,如果你有:

    int32_t combine = (int32_t)(num1 & num2);
    

    它将在num1num2上执行64位AND,然后将其转换为32位以存储在combine中。虽然这与第一种情况完全不同,但combine中存储的结果值将完全相同 - 只有中间值(按位AND的结果)才能看到不同。因此,编译器可以自由地重新排列内容并为这两种情况生成完全相同的代码。

答案 1 :(得分:0)

首先,你没有说num1是什么,所以我们不知道结果应该是什么。其次,4294967040对于int32_t来说太大了。由于您的参数为unsigned long,因此您的其他变量也应如此......但请使用%lu代替%d