-1

I have the following:

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???
}

I'm trying to AND num1 and num2 so that the result would be:

   000000000000000011111111

I'm not sure if I'm ANDing correctly with two different bit lengths or if I should cast.

Any help would be appreciated!

Thanks

4

2 回答 2

2

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

结果,当您拥有:

int32_t combine = (int32_t) num1 & num2;

and num1and num2are both unsigned longand that is 64 bits, 会发生什么:

  1. 演员表将截断num1为 32 位
  2. AND 具有不同的操作数类型(int32_t 和 uint64_t),因此 int32_t 将符号扩展为 64 位。
  3. 对这两个 64 位值执行 AND
  4. 结果被截断回 32 位并存储在combine

现在因为num1是 3232236032 (0xc0a80200),步骤 1 和 2 会将其转换为 0xffffffffc0a80200,这将与 num2 进行“与”运算,然后将丢弃前 32 位。

相反,如果您有:

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

它将在 and 上执行 64 位与num1num2然后截断为 32 位以存储在combine. 虽然这与第一种情况完全不同,但存储的结果值combine将完全相同——只有没有人看到的中间值(按位与的结果)会有所不同。结果,编译器可以自由地重新排列事物并为这两种情况生成完全相同的代码。

于 2013-04-18T16:48:37.503 回答
0

首先,你没有说是什么num1,所以我们不知道结果应该是什么。其次,4294967040 对于int32_t. 既然你的论点是unsigned long,你的其他变量也应该是......但然后使用%lu而不是%d

于 2013-04-18T06:36:22.980 回答