【问题标题】:Bitwise operation: fitsBits function按位运算:fitsBits 函数
【发布时间】:2014-09-19 23:48:27
【问题描述】:

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

//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 n 次向右移动,如果有任何剩余的 1,则表示 x 不适合 n 位。由于我已将 x 向右移动了一位,因此我现在需要将其移动 n-1 次。

我得到的结果是:

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

【问题讨论】:

    标签: binary bit-manipulation bitwise-operators


    【解决方案1】:

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

    对于 2 的补码,n 位... +ve 数必须从 bit(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 值的困难)。但是,假设mask0x7FFFFFFF 结尾,并且(x&gt;&gt;1) 是简单的移位或算术移位,那么:

    • (x&gt;&gt;1)&amp;mask 是 1 的简单移位,如 ((unsigned)x)&gt;&gt;1

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

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

    • 所以,(((x&gt;&gt;1)&amp;mask)&gt;&gt;(~(~n+2)+1))(((unsigned)x)&gt;&gt;1)&gt;&gt;(n-1) 是(鼓)......

      ...((unsigned)x)&gt;&gt;n

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

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

    要测试 signed x 是否适合 signed n 位字段,您需要担心((unsigned)x)&gt;&gt;(n-1) 的值,它必须为零或0xFFFFFFFF&gt;&gt;(n-1),取决于x 的符号。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-04-25
      • 2015-05-25
      • 2012-06-17
      • 1970-01-01
      相关资源
      最近更新 更多