3

標準によると、演算子 << は、負符号付きの最初のオペランドに対して未定義の動作を生成します。

C++11 5.8.2

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-
filled. If E1 has an unsigned type, the value of the result is E1 × 2 pow E2,
reduced modulo one more than the maximum value representable in the result type.
Otherwise, if E1 has a signed type and non-negative value, and E1 × 2 pow E2 is
representable in the result type, then that is the resulting value; otherwise,
the behavior is undefined

メモリ内の整数のレイアウトは実装定義であるため、これは理解できます。

C++11 3.9.1.7

this International Standard permits 2’s complement, 1’s complement and
signed magnitude representations for integral types.

一方、標準では、ビットごとの & | を正確に定義していないようです。そして^するべきです。

C++11 5.11 ビットごとの AND 演算子

and-expression:
    equality-expression
    and-expression & equality-expression
1 The usual arithmetic conversions are performed; the result is the bitwise 
AND function of the operands. The operator applies only to integral
or unscoped enumeration operands.

C++11 5.12 ビット単位の排他的 OR 演算子

exclusive-or-expression:
    and-expression
    exclusive-or-expression ˆ and-expression
1 The usual arithmetic conversions are performed; the result is the bitwise
exclusive OR function of the operands. The operator applies only to integral
or unscoped enumeration operands.

C++11 5.13 ビット単位の包含 OR 演算子

inclusive-or-expression:
    exclusive-or-expression
    inclusive-or-expression | exclusive-or-expression
1 The usual arithmetic conversions are performed; the result is the bitwise
inclusive OR function of its operands. The operator applies only to integral
or unscoped enumeration operands.

これらの演算子の定義は、私には完全にわかりません。それは標準のどこかにありますか?符号付き整数に対して結果の実装が定義されていますか?

例として、次のコードを見てみましょう。

signed char a=-1;
signed char b=3;
signed char c=a&b;

2 の補数では、a は 1111 1111、b は 0000 0011 です。最終的に c は 0000 0011 (+3) に等しくなります。

1 の補数で、a は 1111 1110 で、b は 0000 0011 です。c は 0000 0010 (+2) に等しいですか?

符号の大きさでは、a は 1000 0001 で、b は 0000 0011 です。c は 0000 0001 (+1) に等しいですか?

1 の補数または符号の大きさを使用してプラットフォームにアクセスできる場合、それらのプラットフォームでの結果はどうなりますか?

4

4 に答える 4

5

ビット単位の演算は、数値型の一部として解釈されたときに各ビットが何を意味するかに関係なく、各ビットに対して独立して動作します。

10000001 & 00000011 == 00000001つまり、各ビットが符号を表すか値の一部を表すかに関係なく、はい。

于 2013-01-10T14:37:20.527 に答える
0

ビット単位の& | ^演算子は、2 つのオペランドのそれぞれのすべてのビットの名前付き操作を実行するだけです。これは、基になる型の表現に応じて実装固有になります。

ただし、シフトの場合は事情が異なります。

たとえば、1 バイトの 2 の補数-1=を考えてみましょう11111111。次に、右に 1 つシフトします。今はあなたの数字です127(符号を変える)または-1(0ではなく1を最上位ビットにシフトします)。符号-大きさ表現の場合も同じことが当てはまります。この種の問題をすべて回避するために、標準では単にそれを禁止しています。

于 2013-01-10T14:46:43.080 に答える
0

負の符号付き整数の左シフトと右シフトは、実装で「算術シフト」マシン命令を使用できるようにするために、標準ではそのままの方法で処理されます。算術右シフトは、左に sを挿入する論理右シフトとは異なり、符号ビットを複製します。0算術左シフトは、左端からシフトされたビットが符号ビットと異なる場合、一部のアーキテクチャでオーバーフロー例外を生成する場合があります。したがって、右シフトは実装定義です (結果は常に有効ですが、実装によって異なる場合があるため)。一方、左シフトは未定義です(結果が割り込みになる可能性があるため)。

ビットごとの論理演算子によって生成されるビット パターンは完全に指定されていますが、符号付き整数の場合、結果がトラップ値になる可能性があります ( -01 の補数または符号の大きさのアーキテクチャで-0は が無効な場合など)。この場合、セクション 5 の導入のパラグラフ 4 によると、結果は未定義の動作になります。

式の評価中に、結果が数学的に定義されていないか、その型の表現可能な値の範囲内にない場合、動作は未定義です。

于 2013-01-10T16:11:00.760 に答える
-1

結果は、マシンが整数をどのように表現するかに依存しません。

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0

上記の表は、1 ビットの値を示しています。32 ビット整数を指定すると、ビット計算はすべての 32 ビットに対して実行されます。したがって、ビット単位という用語。

于 2013-01-10T14:36:50.737 に答える