そのような変数に value: を与えると、e = 17|-15;
コンパイル後に答えとして -15 が返されます。算術 c++ が何を使用するのか理解できません。負の小数に対してビット単位の OR 演算を実行するにはどうすればよいですか?
6 に答える
数値のバイナリ表現に対して操作を行っているだけです。あなたの場合、それは2 の補数のようです。
17 -> 00010001
-15 -> 11110001
ご覧のとおりOR
、これら 2 つの数値のビット単位はまだ-15
です。
上記のコメントで、2 の補数表現でこれを試したことを示しましたが、何か間違ったことをしたに違いありません。手順は次のとおりです。
15 -> 00001111 // 15 decimal is 00001111 binary
-15 -> ~00001111 + 1 // negation in two's complement is equvalent to ~x + 1
-15 -> 11110000 + 1 // do the complement
-15 -> 11110001 // add the 1
正の数に対して行うのと同じ方法で、負の数に対して OR 演算を行います。数値はほぼ確実に 2 の補数形式で表され、次の値が得られます。
17 = 0000000000010001 -15 = 1111111111110001
ご覧のとおり、17 のすべてのビットは既に -15 に設定されているため、それらを組み合わせた結果は再び -15 になります。
ビット単位または負の数を使用すると、ビット単位または正の数を使用した場合と同じように機能します。一方の番号のビットは、もう一方の番号のビットと結合されます。プロセッサが負の数をどのように表すかは別の問題です。ほとんどの場合、「2の補数」と呼ばれるものを使用します。これは、基本的に「数値を反転して1を加算する」ことです。
したがって、簡単にするために、8ビットの数値がある場合:
15 is 00001111
Inverted we get 11110000
Add one 11110001
17 is 00010001
Ored together 11110001
17 = b00010001
-15 = b11110001 <--- 2s complement
| -15 = b11110001
演算子|
は「ビット単位OR
」の演算子です。つまり、ターゲットのすべてのビットOR
は、2つのオペランドの対応するビットの組み合わせとして計算されます。つまり、結果のビットは、同じ位置にある数値の2つのビットのいずれか1
がである場合、それ以外の場合はです。1
0
明らかに、結果は数値の2進表現に依存し、これもプラットフォームに依存します。
ほとんどすべてのプラットフォームは、2の補数を使用します。これは、負の数が正の数とは正反対の方向にあり、円を「ラップアラウンド」する符号なし数の円と考えることができます。
符号なし整数:
符号付き整数:
あなたの例の計算は次のとおりです。
17: 00000000 00000000 00000000 00010001
-15: 11111111 11111111 11111111 11110001
------------------------------------------
-15: 11111111 11111111 11111111 11110001
ビットがどのように機能するかを調べる必要があります
基本的に、どちらかの数字が1
特定の場所にある場合、結果にも1
-15 : 11110001 (two's complement)
17 : 00010001
-15 | 17 : 11110001
ご覧のとおり、結果は次のようになります-15