按位运算:fitsBits函数

时间:2014-09-19 23:48:27

标签: binary bit-manipulation bitwise-operators

我在这个网站上看到了这个功能的其他几个实现,但是我很好奇是否有人可以帮我弄清楚为什么这个实现不起作用:

//fitsBits: return 1 if x can be represented as an n-bit, two's complement integer.  
//1<=n<=32 
//Examples: fitsBits(5,3)=0, fitsBits(-4,3)=1
//legal ops: ! ~ & ^ | + << >>
//Max ops: 15

    int fitsBits(int x, int n) {
        int mask = ~(1<<31);
        return !(((x>>1)&mask)>>(~(~n+2)+1));
    }

所以你可以稍微遵循我的逻辑,我向右移动x,这可能会暴露额外的1(算术移位)。所以我创建了一个掩码,以确保它在移动x的其余部分之前变为零。最初我需要向右移动x次,如果有任何剩余的1,则表示x不符合n位。由于我已将x向右移动一位,我现在需要将其移动n-1次。

我得到的结果是:

ERROR: Test fitsBits(2147483647[0x7fffffff],31[0x1f]) failed...
...Gives 1[0x1]. Should be 0[0x0]

1 个答案:

答案 0 :(得分:0)

你所写的内容看起来像C,其中-ve数的右移是“实现定义的”,所以可能是也可能不是算术移位。 (对于左移,情况甚至更糟,-ve值的结果是未定义的。)所以,最好是做所有无符号的琐事。

对于2的补码,n位...... a + ve数必须从位(n-1)向上全'0',而-ve数必须全为'1'...因此,在C假设所有无符号32位整数(没有填充!)......

m = UINT_MAX << (n - 1) ;    // bits from n-1 upwards
q = - (x >> 31) ;            // all sign bits, assuming 32bit integers
return ((x ^ q) & m) == 0 ;

稍后添加......

...我承认我没有努力尝试找出你的代码:

  int fitsBits(int x, int n)
  {
    int mask = ~(1<<31);
    return !(((x>>1)&mask)>>(~(~n+2)+1));
  }

可能正在努力(考虑到转移int值的困难)。但是,假设mask最终为0x7FFFFFFF,而(x>>1)是简单转换或算术转换,那么:

  • (x>>1)&mask是1的简单转换,如((unsigned)x)>>1

  • ~n+2 ~n+1+1-n+1(因为我们假设是2的补码)

  • ~(~n+2)+1 -(~n+2) -(-n+1)n-1

  • 所以,(((x>>1)&mask)>>(~(~n+2)+1))(((unsigned)x)>>1)>>(n-1)(鼓声)......

    ... ((unsigned)x)>>n

...这是为了将x存储在n位字段中而被丢弃的所有位。

如果您想测试x是否适合无符号 n位字段,那么(((unsigned)x)>>n) == 0就可以了。

要测试签名 x是否适合签名的 n位字段,您需要担心{{1}的值},必须为零或((unsigned)x)>>(n-1),具体取决于0xFFFFFFFF>>(n-1)的符号。

(我注意到,顺便提一下,要求是x ...如果1<=n<=32,我们只有符号位,所以我们可以表示-1..0范围内的数字,看起来很奇怪,但仍然是正确的。)