~2 が -3 に等しいのはなぜですか? ~
オペレーターはどのように機能しますか?
18 に答える
負の数は、対応する正の数の2 の補数として格納されることに注意してください。例として、2 の補数での -2 の表現を次に示します: (8 ビット)
1111 1110
これを取得する方法は、数値の 2 進表現を取得し、その補数 (すべてのビットを反転) を取得して 1 を加算することです。2 は 0000 0010 から始まり、ビットを反転すると 1111 1101 になります。1 を追加すると、上記の結果が得られます。最初のビットは負を意味する符号ビットです。
それでは、~2 = -3 を得る方法を見てみましょう。
再び2つです:
0000 0010
すべてのビットを反転するだけで、次のようになります。
1111 1101
では、-3 は 2 の補数でどのように見えるでしょうか? 正の 3: 0000 0011 で開始し、すべてのビットを 1111 1100 に反転し、1 を追加して負の値 (-3)、1111 1101 にします。
したがって、単純に 2 のビットを反転すると、2 の補数表現である -3 が得られます。
補数演算子 (~) JUST FLIPS BITS。これらのビットを解釈するのはマシン次第です。
~
値のビットを反転します。
数値がビット単位でどのように表現されるかに関係があるのはなぜですか~2
。-3
数値は2 の補数で表されます。
したがって、2 はバイナリ値です。
00000010
そして ~2 はビットを反転するので、値は次のようになります:
11111101
これは、-3 のバイナリ表現です。
他の人が述べたよう~
に、ビットを反転しただけで(1を0に、0を1に変更)、2の補数が使用されるため、見た結果が得られます。
追加する1つのことは、2の補数が使用される理由です。これは、負の数の演算が正の数の演算と同じになるようにするためです。ゼロを取得するために加算する必要-3
のある数と考えてください。この数は次のようになります。2進数の加算は小学校(10進数)の加算と同じであり、10ではなく2になったら1を実行するだけです。 。3
1101
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
したがって、1101
は-3
、取得したビットを0010
2つ反転します。
この操作は補完であり、否定ではありません。
〜0 = -1と考えて、そこから作業します。
否定のアルゴリズムは、「補数、増分」です。
知ってますか?逆数が対称で、0と-0の両方を持つ「1の補数」もあります。
この質問に対する回答はかなり前に投稿されていることは知っていますが、同じ回答を共有したいと思いました。
数値の 1 の補数を見つけるには、まずその 2 進数に相当するものを見つけます。ここで、10 進数2
は 2 進数で表され0000 0010
ます。ここで、バイナリ表現のすべての桁を反転する (すべての 1 を 0 に、すべての 0 を 1 に反転する) ことによって、その 1 の補数を取ると、次のようになります。
0000 0010 → 1111 1101
これは 10 進数 2 の 1 の補数です。2 進数では最初のビット、つまり符号ビットが 1 であるため、格納されている数値の符号が負であることを意味します。(ここでいう数は2 ではなく2 の 1 の補数)。
ここで、数値は 2 の補数 (数値プラス 1 の 1 の補数を取る) として格納されるため、この 2 進数1111 1101
を 10 進数で表示するには、まずその 2 の補数を見つける必要があります。これは次のようになります。
1111 1101 → 0000 0010 + 1 → 0000 0011
これが 2 の補数です。2 進数 の 10 進数表現0000 0011
は です3
。そして、前述のように符号ビットが 1 だったので、結果の答えは-3
です。
ヒント:この手順を注意深く読んだ場合、1 の補数演算子の結果は、実際には、数値 (オペランド - この演算子が適用されるオペランド) に負符号付きの 1 を加えたものであることがわかります。他の数値でもこれを試すことができます。
ビット単位の補数演算子 (~) は単項演算子です。
以下の方法で動作します
最初に、指定された 10 進数を対応する 2 進数値に変換します。つまり 、2 の場合、最初に 2 を 0000 0010 (8 ビットの 2 進数) に変換します。
次に、数字のすべての 1 を 0 に変換し、すべてのゼロを 1 に変換します。数字は 1111 1101 になります。
これは -3 の 2 の補数表現です。
補数を使用して符号なしの値を見つける、つまり 1111 1101 を 10 進数 (=4294967293) に変換するには、印刷中に %u を使用するだけです。
ただ…………
任意の数値の 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
ポイントは、マイナスが来る場所です。私の意見では、32 ビット レジスタがあり、これは 2^31 -1 ビットが操作に関与し、通常は 1 である符号ビットとして格納される以前の計算 (補数) で変化する 1 ビットを休止することを想定しています。結果は ~10 = -11 になります。
~(-11) =10;
上記は、printf("%d",~0); の場合に当てはまります。結果が得られます: -1;
しかし、結果よりも printf("%u",~0): 32 ビット マシンでは 4294967295 です。
基本的にアクションは否定ではなく補完です。
ここで x= ~x は結果 -(x+1) を常に生成します。
x = ~2
-(2+1)
-3
それは簡単です:
Before starting please remember that
1 Positive numbers are represented directly into the memory.
2. Whereas, negative numbers are stored in the form of 2's compliment.
3. If MSB(Most Significant bit) is 1 then the number is negative otherwise number is
positive.
あなたは〜2を見つけています:
Step:1 Represent 2 in a binary format
We will get, 0000 0010
Step:2 Now we have to find ~2(means 1's compliment of 2)
1's compliment
0000 0010 =================> 1111 1101
So, ~2 === 1111 1101, Here MSB(Most significant Bit) is 1(means negative value). So,
In memory it will be represented as 2's compliment(To find 2's compliment first we
have to find 1's compliment and then add 1 to it.)
Step3: Finding 2's compliment of ~2 i.e 1111 1101
1's compliment Adding 1 to it
1111 1101 =====================> 0000 0010 =================> 0000 0010
+ 1
---------
0000 0011
So, 2's compliment of 1111 1101, is 0000 0011
Step4: Converting back to decimal format.
binary format
0000 0011 ==============> 3
In step2: we have seen that the number is negative number so the final answer would
be -3
So, ~2 === -3
tl;dr ~
はビットを反転します。その結果、記号が変わります。~2
は負の数 ( 0b..101
) です。負の数を出力するには、 を出力しruby
、-
次に : の 2 の補数を出力し~2
ます-(~~2 + 1) == -(2 + 1) == 3
。正数はそのまま出力されます。
内部値とその文字列表現があります。正の整数の場合、それらは基本的に一致します。
irb(main):001:0> '%i' % 2
=> "2"
irb(main):002:0> 2
=> 2
後者は次と同等です。
irb(main):003:0> 2.to_s
"2"
~
内部値のビットを反転します。2
です0b010
。~2
です0b..101
。2 つのドット ( ..
) は、無数の を表し1
ます。結果の最上位ビット (MSB) は であるため1
、結果は負の数 ( (~2).negative? == true
) になります。負の数を出力するruby
に-
は、内部値の 2 の補数を出力します。2 の補数は、ビットを反転してから を加算することによって計算され1
ます。の 2 の補数は0b..101
です3
。そのような:
irb(main):005:0> '%b' % 2
=> "10"
irb(main):006:0> '%b' % ~2
=> "..101"
irb(main):007:0> ~2
=> -3
要約すると、ビットを反転させて符号を変更します。負の数を出力するには、 を出力して-
から~~2 + 1
( ~~2 == 2
) を出力します。
このように負の数を出力する理由ruby
は、格納された値を絶対値の 2 の補数として扱うためです。つまり、格納されるのは0b..101
. これは負の数であり、ある値の 2 の補数ですx
。を見つけるx
には、 の 2 の補数を実行し0b..101
ます。これは の 2 の補数の 2 の補数ですx
。これはx
(例~(~2 + 1) + 1 == 2
)です。
負の数に適用する場合は~
、ビットを反転するだけです (それでも符号が変わります)。
irb(main):008:0> '%b' % -3
=> "..101"
irb(main):009:0> '%b' % ~-3
=> "10"
irb(main):010:0> ~-3
=> 2
さらに紛らわしいのは、それ~0xffffff00 != 0xff
(または MSB が に等しい他の値1
) です。少し単純化してみましょう~0xf0 != 0x0f
。これは0xf0
、正の数として扱われるためです。これは実際には理にかなっています。だから、~0xf0 == 0x..f0f
。結果は負の数です。の 2 の補数は0x..f0f
です0xf1
。そう:
irb(main):011:0> '%x' % ~0xf0
=> "..f0f"
irb(main):012:0> (~0xf0).to_s(16)
=> "-f1"
~
結果にビット単位の演算子を適用しない場合は、次のように-x - 1
演算子と見なすことができます。
irb(main):018:0> -2 - 1
=> -3
irb(main):019:0> --3 - 1
=> 2
しかし、それはあまり役に立たないことは間違いありません。
例8 ビット (簡単にするため) のネットマスクが与えられ、 の数を計算したいとしましょう0
。bit_length
ビットを反転して( )を呼び出すことで計算できます0x0f.bit_length == 4
。しかし~0xf0 == 0x..f0f
、そのため、不要なビットを切り取る必要があります。
irb(main):014:0> '%x' % (~0xf0 & 0xff)
=> "f"
irb(main):015:0> (~0xf0 & 0xff).bit_length
=> 4
^
または、XOR 演算子 ( )を使用できます。
irb(main):016:0> i = 0xf0
irb(main):017:0> '%x' % i ^ ((1 << i.bit_length) - 1)
=> "f"
ビット単位の演算子は、私の経験と知識に従って、符号と大きさの方法で機能する単項演算子です。
たとえば、~2 は -3 になります。
これは、MSB が符号ビットである 0000 0010 (8 ビット演算子) であるビット単位の演算子が最初に符号と大きさで数値を表すためです。
その後、-2 である 2 の負の数を取ります。
-2 は、符号と大きさで 1000 0010 (8 ビット演算子) として表されます。
後で LSB (1000 0010 + 1) に 1 を追加すると、1000 0011 になります。
これは -3 です。