7

私はJavaでビット単位の計算機を作成しようとしています.〜101などの式を入力でき、このコードを実行すると10が返されます.

import java.util.Scanner;

public class Test
{
    public static void main(String[] args)
    {
        Integer a = Integer.valueOf("101", 2);
        System.out.println(Integer.toString(~a,2));
    }
}

-110を出力するのはなぜですか?

4

5 に答える 5

11

101 は 3 ビット長であると想定しています。Java は可変長ビット操作をサポートしていません。それintはビット全体で動作するため~not32 ビット長の「101」になります。

---「どうしたら直せますか?」と聞かれて編集。---

とても良い質問ですが、答えは「できない」と「同じことを別の手段で達成できる」の組み合わせです。

~オペレーターが行うことを行うため、オペレーターを修正することはできません。+1 の位だけを追加するように修正を求めるようなものです。起こらないだけです。

目的の操作を実現できますが、それを実行するにはもう少し「もの」が必要です。最初に、対象のビットを指定する何か(別の int)が必要です。これは通常、ビット マスクと呼ばれます。

 int mask = 0x00000007; // just the last 3 bits.

 int masked_inverse = (~value) & mask;

私たちが行ったことは、実際には 32 ビットを反転し、それらのビットのうち 29 ビットをゼロにしたことに注意してください。なぜなら、それらはマスクでゼロに設定されているためです。これは、「それらを気にしない」ことを意味します。&これは、「設定されていて、それを気にかけている場合は、設定してください」と言うように演算子を活用していると想像することもできます。

これで 32 ビットのままですが、下位 3 のみが反転されます。3 ビットのデータ構造が必要な場合は、話は別です。Java (およびほとんどの言語) は、そのようなことを直接サポートしていません。そのため、それをサポートするために Java に別のを追加したくなるかもしれません。Java はクラスメカニズムを介して型を追加しますが、組み込みの型は変更できません。これは、3 ビットのデータ構造を表すクラスを作成できることを意味しますが、int を内部で 32 ビット フィールドとして処理する必要があります。

幸いなことに、誰かがすでにこれを行っています。これは標準 Java ライブラリの一部でありBitSet .

BitSet threeBits = new BitSet(3);
threeBits.set(2);  // set bit index 2
threeBits.set(0);  // set bit index 0
threeBits.flip(0,3);

ただし、このようなビット操作は、Java で新しい型を追加する唯一の方法としてクラスを定義することから派生する、Java のクラス/オブジェクト システムの制約により、異なる感覚を持ちます。

于 2013-03-22T16:48:45.130 に答える
0

toString() メソッドは、その引数を符号付きの値として解釈します。

二項演算を実証するには、 を使用することをお勧めしますInteger.toBinaryString()。引数を符号なしと解釈するため、~101 は 111111111111111111111111111010 として出力されます。

出力のビット数を減らしたい場合は、& で結果をマスクできます。

于 2013-03-22T16:46:19.793 に答える
0

整数の 101 は、実際には00000000000000000000000000000101これを否定するものとして表され、得られる11111111111111111111111111111010- これは-6です。

于 2013-03-22T16:46:58.647 に答える
0

エドウィンの答えを少し詳しく説明すると、可変長のマスクを作成して関心のあるビットを開発する場合は、いくつかのヘルパー関数が必要になる場合があります。

/**
 * Negate a number, specifying the bits of interest.
 * 
 * Negating 52 with an interest of 6 would result in 11 (from 110100 to 001011).
 * Negating 0 with an interest of 32 would result in -1 (equivalent to ~0).
 * 
 * @param number the number to negate.
 * @param bitsOfInterest the bits we're interested in limiting ourself to (32 maximum).
 * @return the negated number.
 */
public int negate(int number, int bitsOfInterest) {
    int negated = ~number;
    int mask = ~0 >>> (32 - bitsOfInterest);
    logger.info("Mask for negation is [" + Integer.toBinaryString(mask) + "]");
    return negated & mask;
}

/**
 * Negate a number, assuming we're interesting in negation of all 31 bits (exluding the sign).
 * 
 * Negating 32 in this case would result in ({@link Integer#MAX_VALUE} - 32).
 * 
 * @param number the number to negate.
 * @return the negated number.
 */
public int negate(int number) {
    return negate(number, 31);
}
于 2014-04-18T02:21:14.787 に答える