2

このメソッドは、絶対値を取得しようとしている n ビットの 2 の補数と、その数値が得られるビット数を受け取ります。ここではいくつかの例を示します。

腹筋 (0x00001234, 16); // => 0x00001234

abs(0x00001234, 13); // => 0x00000DCC

したがって、最初の例では、0x00001234 が 0x00001234 であることがわかります。これは、16 ビットでは、それ自体であるのに十分な先行ゼロがあるためです。

ただし、2 番目の例では、13 ビットを使用すると 0x00001234 の符号ビットが 1 になるため、この 13 ビットの数値を正の数値に変換すると、0x00000DCC が得られます。

これまでのところうまくいくはずですが、場合によってはうまくいきません:/何が間違っているのか、どの方向に進むべきなのか、何か考えはありますか?

編集: また、言及するのを忘れていましたが、1 だけインクリメントしない限り、>>> や +、-、*、/ は使用できません。

public static int abs(int num, int n)
{

    boolean set = ((1 << n-1) & num) == (1 << n-1);
    if (!set) {
        return num;
    } else {
        int bitmask = (0x7FFFFFFF >> (32-n)) | (1 << n-1);
        return (num ^ bitmask) + 1;
    }
}
4

2 に答える 2

2

わあ、ここであなたは後で来る人々のために行きます:

  public static int abs(int num, int n)
  {
      int topbit = 1<<(n-1);
      int ones = (topbit<<1)-1;
      num &= ones;                     // sanity check
      if (0==(topbit&num)) {
          return num;
      } else {
          return (num ^ ones) + 1;
      }
  }

問題は、この機能を高速化するために、ここから操作を削除できるかどうかです。

于 2013-01-20T07:13:50.037 に答える
0

これは間違っています

int bitmask = 0xFFFFFFFF >> (32 - n);

常に 0xFFFFFFFF になります。

int bitmask = 0xFFFFFFFF >>> (32 - n);

http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19を参照してください。

あなたのコメントから理解したように、UPDATEは unsigned shift の使用を許可されていません。この場合、試してください

    int bitmask = (int) (0xFFFFFFFFL >> (32 - n));

完全なコード

public static int abs(int num, int n) {
    int bitmask = (int) (0xFFFFFFFFL >> (32 - n));
    boolean set = ((1 << n - 1) & num) != 0;
    if (!set) {
        return num & bitmask;
    } else {
        return -(num | ~bitmask);
    }
}
于 2013-01-20T06:07:51.490 に答える