10

このコードがそのように機能する方法と理由を理解するのに苦労しています。この割り当ての私のパートナーはこの部分を完了しましたが、これがどのように、そしてなぜ機能するのかを知るために彼に連絡することはできません. 私はそれを理解するためにいくつかの異なることを試みましたが、どんな助けでも大歓迎です。このコードは、2 の補数と 32 ビット表現を使用しています。

/* 
 * 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
 *   Rating: 2
 */
int fitsBits(int x, int n) {
    int r, c;
    c = 33 + ~n;
    r = !(((x << c)>>c)^x);
    return r;
}
4

3 に答える 3

14
  • 2 の補数プラットフォーム-nでは、 と同等~n + 1です。このため、c = 33 + ~nそのようなプラットフォームでは実際には と同等c = 32 - nです。これは、下位ビットが占有されている場合に、32 ビット値cに残っている上位ビットの数を表すことを目的としています。intn

    このコードに存在する 2 つのプラットフォーム依存関係に注意してください: 2 の補数プラットフォーム、32 ビットint型。

  • 次に、それらの上位ビットを符号で埋める((x << c) >> cことを目的としています。サインフィルは、ビット位置にある の値、これらの上位ビットをゼロにする必要があることを意味します。しかし、 bit-positionにある の値については、これらの上位ビットをs で埋める必要があります。これは、 の負の値に対してコードを適切に機能させるために重要です。cx0n - 1x1n - 11x

    これにより、別の 2 つのプラットフォーム依存が導入されます。<<負の値をシフトするとき、または1符号ビットにシフトされるときに適切に動作する演算子 (正式には未定義の動作) と、>>負の値をシフトするときに符号拡張を実行する演算子 (正式には実装定義です) )

  • 残りは、上で答えたように、x:の元の値との比較だけ!(a ^ b)ですa == b。上記の変換が の元の値を破壊しなかった場合、実際には 2 の補数表現の下位ビットに適合しxます。xn

于 2015-08-30T03:22:07.527 に答える
14
c = 33 + ~n;

これは、下位ビットを使用した後に上位ビットがいくつ残っているかを計算しnます。

((x << c)>>c

これにより、上位ビットが の符号ビットと同じ値で埋められますx

!(blah ^ x)

これは、

blah == x
于 2013-02-09T22:59:49.320 に答える