奇数位移位导致C#

时间:2011-07-20 15:38:00

标签: c# .net bitwise-operators fixed bit-shift

鉴于我的uint值为2402914,并且我想获取最左边的17位,通过执行此代码,我的逻辑中出现了错误:

int testop = 0;
byte[] myArray = BitConverter.GetBytes(2402914);    
fixed (byte* p = &myArray[0])    
{   
    testop = *p >> 15;    
}

我的预期输出是

50516.

4 个答案:

答案 0 :(得分:3)

您可能希望得到与现实相符的期望。右移相当于除以2.你实际上除以2 15次,这与说你除以2 ^ 15 = 32768相同。注意2402914/32768 = 73(截断余数)。 / p>

因此,我希望结果是73,而不是50516。

事实上,

2402914_10 = 0000 0000 0010 0100 1010 1010 0110 0010_2

这样最左边的17位是

             0000 0000 0010 0100 1

请注意

0000 0000 0010 0100 1 = 1 * 1 + 0 * 2 + 0 * 4 + 1 * 8 + 0 * 16 + 0 * 32 + 1 * 64 
                      = 73

请注意,您可以使用

更简单地获得此结果
int testop = 2402914 >> 15;

答案 1 :(得分:1)

*p只给你第一个字节;它相当于p[0]。您将不得不使用移位和ORing来组合前三个字节(或最后三个字节,取决于字节顺序...)的位。

如果这段代码不是更复杂的简化版本,而你实际上只想从int中提取最左边的17位,那么应该这样做:

int testop = (someInt >> 15) & 0x1ffff;

(编辑:添加& 0x1ffff以使其适用于负整数;感谢@James。)

答案 2 :(得分:1)

哇,这是一个非常有趣的谜题。不是编程部分,而是试图弄清楚你在哪里得到了数字50516以及你要用你的代码做什么。看起来你正在采用16个最低有效位并将它们旋转到9位左右。

2402914: 0000 0000 0010 0100 1010 1010 0110 0010
 left 9: 0100 1001 0101 0100 1100 010 
  match:                     ^^^^ ^^^  
>>50516:                     1100 0101 0101 0100
  match:                             ^ ^^^^ ^^^^
right 7:                             1 0101 0100 110 0010

int value2 = value & 0xffff;
int rotate9left = ((value2 << 9) & 0xffff) | ((value2) >> (16 - 9));

我不知道你为什么使用字节数组,但似乎你认为你的fixed()语句循环遍历数组,而不是。你在固定块中的语句是取myArray[0]处的字节值并将其向右移15位(将填充移位为0而不是旋转将前端包裹到后面)。任何超过8的东西都会给你零。

答案 3 :(得分:0)

据我所知,您可以将位移操作符直接应用于int数据类型,而不是经历不安全代码的麻烦。

例如:

2402914 >> 15 = 73

这与杰森预测的结果有关。

此外,我注意到

2402914 >> 5 = 75091
and 2402914 >> 6 = 37545

这表明任何类似的权利转移都无法达到您所需的结果。