web-dev-qa-db-ja.com

ビットごとの補数演算子(〜チルダ)はどのように機能しますか?

〜2が-3に等しいのはなぜですか? ~演算子はどのように機能しますか?

163
bala

負の数値は、正の相対値の2の補数として格納されることに注意してください。例として、2の補数の-2の表現を次に示します。(8ビット)

1111 1110

これを得る方法は、数値のバイナリ表現を取り、その補数(すべてのビットを反転)を取り、1を加算することです。 2つは0000 0010から始まり、ビットを反転することで1111 1101が得られます。1つを追加すると上記の結果が得られます。最初のビットは符号ビットであり、負を意味します。

それでは、〜2 = -3を取得する方法を見てみましょう。

再び2つです。

0000 0010

すべてのビットを反転させるだけで、次の結果が得られます。

1111 1101

2の補数で-3はどのように見えますか?正の3から開始:0000 0011、すべてのビットを1111 1100に反転し、1を追加して負の値(-3)、1111 1101にします。

したがって、2のビットを単純に反転すると、-3の2の補数表現が得られます。

補数演算子(〜)JUST FLIPS BITS。これらのビットを解釈するのはマシン次第です。

256
Anthony

~は、値のビットを反転します。

~2-3である理由は、数値がビット単位で表される方法に関係しています。数字は 2の補数 で表されます。

したがって、2はバイナリ値です

00000010

〜2はビットを反転するため、値は次のようになります。

11111101

これは、-3のバイナリ表現です。

35
driis

他の人が言及したように~はビットを反転させ(1から0、0から1に変更)、 2の補数 が使用されるため、見た結果が得られます。

追加する1つのことは、why2の補数が使用されることです。これは、負の数の操作が正の数の操作と同じになるようにするためです。 -3は、ゼロを取得するために3を追加する必要がある数と考えてください。この数は1101であることがわかります。 10ではなく。

 1101 +
 0011 // 3
    =
10000
    =
 0000 // lose carry bit because integers have a constant number of bits.

したがって、1101-3であり、取得するビットを反転して0010(2)にします。

15
Motti

この操作は、否定ではなく補完です。

〜0 = -1と考えて、そこから動作します。

否定のアルゴリズムは、「補数、増分」です。

知ってますか?逆数are対称の「1の補数」もあり、0と-0の両方があります。

8
gbarry

私はこの質問に対する回答がかなり前に投稿されたことを知っていますが、同じ質問に対する回答を共有したいと思いました。

数値の1の補数を見つけるには、最初にその同等のバイナリを見つけます。ここでは、10進数2は、バイナリ形式の0000 0010として表されます。ここで、バイナリ表現のすべての数字を反転(すべての1を0に、すべての0を1に反転)することにより、1の補数を取り、次のようになります。

0000 0010 → 1111 1101

これは、10進数2の1の補数です。また、最初のビット、つまり符号ビットは2進数の1であるため、符号は格納された数値に対してであることを意味します。 (ここで、参照される数はnot 2ですが、2の補数です)。

ここで、数値は2の補数として格納されるため(数値と1の補数を取得)、この2進数1111 1101を10進数で表示するには、最初に2の補数を見つける必要があります。

1111 1101 → 0000 0010 + 1 → 0000 0011

これは2の補数です。 2進数の10進数表現0000 00113です。また、上記のように符号ビットが1であったため、結果の答えは-3です。

ヒント:この手順を注意深く読んだ場合、1の補数演算子の結果は、実際には、数字(この演算子が適用されるオペランド)と負符号の付いたものであることがわかります。 。他の番号でもこれを試すことができます。

5

int a = 4; System.out.println(〜a);結果は:-5

Javaの整数の「〜」は、noの1の補数を表します。たとえば、私は〜4を取っています。これは、バイナリ表現0100を意味します。まず、整数の長さは4バイト、つまり4 * 8(1バイトの8ビット)= 32です。したがって、システムメモリ4では0000 0000 0000 0000 0000 0000 0000 0000 0100として表されます〜演算子は上記のバイナリで1の補数を実行します

すなわち、1111 1111 1111 1111 1111 1111 1111 1011-> 1の補数は、1の場合はno(-または+)の符号を表し、0の場合は符号が '-'で、符号が '+'の場合この結果は負の数です。Javaでは、負の数は2の補数形式で格納されます。取得した結果は2の補数に変換する必要があります(最初に1の補数を実行し、1の補数を1だけ追加します)。最上位ビット1(これは数値の符号表現であり、残りの31ビットを意味する1111 1111 1111 1111 1111 1111 1111 1011(〜演算子の取得結果)1000 0000 0000 0000 0000 0000 0000を除いて、すべて1がゼロになります。 0100(1の補数)

1 (2's complement)

1000 0000 0000 0000 0000 0000 0000 0101結果は-5です。ビデオのこのリンクを確認してください<[Javaのビット演算子] https://youtu.be/w4pJ4cGWe9Y

4
Mike Aluydiav

単に...........

任意の数の2の補数として、1を追加するよりもすべての1を0に、またはその逆に反転することで計算できます。

ここで、N =〜Nは常に結果-(N + 1)を生成します。システムは2の補数の形式でデータを保存するため、このように〜Nを保存します。

  ~N = -(~(~N)+1) =-(N+1). 

例えば::

  N = 10  = 1010
  Than ~N  = 0101
  so ~(~N) = 1010
  so ~(~N) +1 = 1011 

今ポイントはマイナスが来るところからです。私の意見では、操作に関与する2 ^ 31 -1ビットを意味する32ビットのレジスタがあり、以前の計算(補数)で変化する1ビットを通常1である符号ビットとして格納するとします。そして、結果は〜10 = -11になります。

〜(-11)= 10;

Printf( "%d"、〜0);の場合、上記は真です。結果が得られます:-1;

ただし、printf( "%u"、〜0)の結果は32ビットマシンでは4294967295です。

ほとんどの人にとって、混乱の部分は10進数と符号付き2進数の違いに起因していると思うので、最初に明確にしましょう。

人間の10進数の世界の場合:01は1を意味し、-01はコンピューターのバイナリの世界の場合-1を意味します:符号なしの場合、101は5を意味します。 101は、符号付き数字が位置xにあるときに符号が付けられている場合、(-4 + 1)を意味します。 |バツ

2の反転ビット=〜2 =〜(010)= 101 = -4 + 1 = -3

1
user7537910

ビット単位の補数演算子(〜)は単項演算子です。

次の方法に従って動作します

まず、指定された10進数を、対応するbinary値に変換します。2の場合、最初に2を0000 0010(8ビットの2進数に変換)に変換します。 )。

次に、数値のすべての1を0に、すべてのゼロを1に変換します。その後、数値は1111 1101になります。

これは、-3の2の補数表現です。

補数を使用して符号なしの値を見つけるには、つまり単に1111 1101を10進数(= 4294967293)に変換するには、印刷中に%uを使用するだけです。

1
james.bondu

基本的にアクションは否定ではなく補数です。

ここでx =〜xは結果を生成します-(x + 1)常に。

x =〜2

-(2 + 1)

-3

0
Sunil

最初に、指定された数字を2進数に分割し、最後の2進数に追加して逆にする必要があります。この実行後、前の数字と反対の符号を与えて、有能な〜2 = -3を見つけます。 :2sバイナリ形式は00000010から11111101への変更であり、これは1の補数であり、その後、00000010 + 1 = 00000011が3のバイナリ形式であり、-sign Ie、-3

0
balusabavath

Javascriptチルダ(〜)は、指定された値を1の補数に強制します。すべてのビットが反転します。それはすべてチルダが行います。意見を述べるサインではありません。 数量の加算も減算もしません。

0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]

JavaScriptのような高水準言語を使用する標準デスクトッププロセッサでは、BASE10符号付き演算が最も一般的ですが、それが唯一の種類ではないことに注意してください。 CPUレベルのビットは、多くの要因に基づいて解釈されます。 「コード」レベル、この場合はJavaScriptでは、定義により32ビットの符号付き整数として解釈されます(これからfloatを残しましょう)。それを量子と考えてください。これらの32ビットは一度に多くの可能な値を表します。それはあなたがそれらを通して見る変換レンズに完全に依存します。

JavaScript Tilde operation (1's complement)

BASE2 lens
~0001 -> 1110  - end result of ~ bitwise operation

BASE10 Signed lens (typical JS implementation)
~1  -> -2 

BASE10 Unsigned lens 
~1  -> 14 

上記のすべてが同時に当てはまります。

0
Elvn

ビット単位演算子は、私の経験と知識に従って、符号と大きさの方法で動作する単項演算子です。

たとえば、〜2は-3になります。

これは、ビット単位演算子が最初に0000 0010(8ビット演算子)の符号と大きさで数値を表すため、MSBが符号ビットであるためです。

その後、-2の負の数である-2になります。

-2は、符号と大きさが1000 0010(8ビット演算子)として表されます。

その後、LSBに1が追加され(1000 0010 + 1)、1000 0011になります。

-3です。