回答:
負の数は、正の数の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の補数表現が得られます。
~
値のビットを反転します。
なぜ、~2
ある-3
数字をビット単位の表現方法に関係していますが。数値は2の補数として表されます。
つまり、2はバイナリ値です
00000010
そして、〜2はビットを反転するので、値は次のようになります。
11111101
これは、-3のバイナリ表現です。
他の人が言及したよう~
に、ビットを反転しただけで(1を0に、0を1に変更)、2の補数以降が使用されるため、見た結果が得られます。
追加することの1つは、 2の補数が使用される理由です。これは、負の数の演算が正の数の演算と同じになるようにするためです。ゼロを取得するために追加する必要が-3
ある数と考えて3
ください。この数は1101
であることがわかります。バイナリの加算は小学校(10進数)の加算と同じで、10ではなく2に到達したときに1を加算するだけです。 。
1101 +
0011 // 3
=
10000
=
0000 // lose carry bit because integers have a constant number of bits.
したがって、1101
は-3
、取得するビットを0010
2つ反転させます。
この質問の回答が長い間投稿されていることは知っていますが、同じ質問に対する回答を共有したいと思いました。
数値の1の補数を見つけるには、まずその2進数の等価物を見つけます。ここでは、10進数2
は0000 0010
バイナリ形式で表されます。次に、バイナリ表現のすべての桁を反転(すべての1を0に、すべての0を1に反転)することで、その1の補数を取得します。
0000 0010 → 1111 1101
これは、10進数2の1の補数です。また、最初のビット、つまり符号ビットは2進数で1であるため、格納されている数に対して符号が負であることを意味します。(ここでは、言及された数は 2ではなく、2の補数です)。
ここで、数値は2の補数として格納されるため(数値の1の補数に1を加えたもの)、この2進数1111 1101
を10 進数に表示するには、最初に2の補数を見つける必要があります。
1111 1101 → 0000 0010 + 1 → 0000 0011
これは2の補数です。2進数の10進数表現0000 0011
は3
です。そして、上記のように符号ビットは1だったので、結果の答えは-3
です。
ヒント:この手順を注意深く読んだ場合、1の補数演算子の結果は、実際には数値(この演算子が適用されるオペランド-)に負の符号が付いたものになります。他の番号でもこれを試すことができます。
add, flip, add
。0010
-> 0011
-> 1100
->1101
0010
1101
0010
NOT 0 = 1
そしてNOT 1 = 0
。4ビットシステムでは、NOT 0011
(3)= 1100
(12符号なし、-4符号付き)。私の理解から、2の補数はと定義され(NOT n) + 1
、ビット数に関係なく、数値の負の対応を見つけるために使用されます。したがって、2c(5) = -5
。ほら、今、それは完全に理にかなっています。この操作をそれが何であるかを呼び出す限り、ビット単位のNOTです。
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 0100として表されます。ここで〜演算子は、上記のバイナリに対して1の補数を実行します
つまり、1111 1111 1111 1111 1111 1111 1111 1011-> 1の補数の最上位ビットは、1の場合はno(-または+)の符号を表し、0の場合は符号-、次に0の場合は符号+になります。これは、私たちの結果が負の数です。Javaでは、負の数は2の補数形式で格納されます。取得した結果は、2の補数に変換する必要があります(最初に1の補数を実行し、1の補数を追加するだけです)。最上位ビット1(数値の符号表現)を除き、すべて1がゼロになります。つまり、残りの31ビットは1111 1111 1111 1111 1111 1111 1111 1011(〜演算子の取得結果)1000 0000 0000 0000 0000 0000 0000 0100(1の補数)
1000 0000 0000 0000 0000 0000 0000 0101これで結果は-5になります。ビデオのこのリンクを確認してください<[Javaのビット単位の演算子] https://youtu.be/w4pJ4cGWe9Y
単に...........
任意の数の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。
ビット単位の補数演算子(〜)は単項演算子です。
以下の方法で機能します
最初に、指定された10進数を対応するバイナリ値に 変換します.2の場合、最初に2を0000 0010に変換します(8ビットの2進数に)。
次に、数値のすべての1を0に、すべてのゼロを1に変換します。その後、数値は1111 1101になります。
これは、-3の2の補数表現です。
補数を使用して、つまり単に1111 1101を10進数(= 4294967293)に変換するために符号なしの値を見つけるには、印刷中に%uを使用するだけです。
ほとんどの人にとって混乱の部分は10進数と符号付き2進数の違いによるものだと思うので、まずそれを明確にしましょう。
人間の10進数の世界の場合:01は1を意味し、-01は-1を意味します。コンピューターのバイナリの世界の場合:101は、符号なしの場合は5を意味します。101は、符号付き数字が位置xにあるときに符号付きの場合、(-4 + 1)を意味します。| バツ
したがって、2の反転ビット=〜2 =〜(010)= 101 = -4 + 1 = -3混乱は、署名された結果(101 = -3)と署名されていない結果(101 = 5)の混合によるものです。
tl; dr ~
はビットを反転します。その結果、サインが変わります。~2
負の数(0b..101
)です。負の数を出力するにはruby
prints -
、次に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進数に分割し、最後の2進数に追加することによって逆にする必要があります。この実行後、前の数字とは反対の符号を与えなければなりません〜2 = -3 :2sバイナリ形式は00000010から11111101への変更これは1の補数であり、次に00000010 + 1 = 00000011が補完されます。これは3のバイナリ形式であり、-sign Ie、-3
ビット単位の演算子は、私の経験と知識に従って、符号と大きさの方法で機能する単項演算子です。
たとえば、〜2は-3になります。
これは、MSBが符号ビットである場合、ビットごとの演算子は最初に0000 0010(8ビット演算子)である符号と大きさで数値を表すためです。
その後、2の負の数、つまり-2が使用されます。
-2は、符号と大きさで1000 0010(8ビット演算子)として表されます。
その後、LSBに1が追加され(1000 0010 + 1)、1000 0011になります。
-3です。
JavaScriptのチルダ(〜)は、指定された値を1の補数に変換します。すべてのビットが反転されます。 それがチルダのすべてです。意欲的なサインではありません。数量は加算も減算もされません。
0 -> 1
1 -> 0
...in every bit position [0...integer nbr of bits - 1]
JavaScriptのような高水準言語を使用する標準のデスクトッププロセッサでは、BASE10符号付き算術が最も一般的ですが、覚えておいてください。それが唯一の種類ではありません。CPUレベルのビットは、いくつかの要因に基づいて解釈されます。「コード」レベルでは、この場合はJavaScriptであり、定義により32ビットの符号付き整数として解釈されます(フロートはこれに任せましょう)。量子と考えてください。これらの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
上記のすべてが同時に当てはまります。